Commit Graph

38989 Commits

Author SHA1 Message Date
Peter Steinberger 0890f7f914 fix(ci): repair main test and script type checks (#109826) 2026-07-17 10:33:55 +01:00
Monkey-wusky 065223c438 fix(apns): cancel redirect relay response body before returning (#109728)
* fix(apns): cancel redirect relay response body before returning

* test: fold APNS redirect body cleanup proof

Co-authored-by: 毛宇豪0668001457 <mao.yuhao@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-17 10:25:00 +01:00
Peter Steinberger 01961bbd38 fix(ci): restore web push migration lint (#109845) 2026-07-17 10:24:06 +01:00
wangmiao0668000666 bd7b0ad85f fix(plugins): remove abort listener when channel runtime context is disposed (#109708) 2026-07-17 10:11:21 +01:00
Peter Steinberger 62db322715 chore(channels): mark the legacy plan-step wire branch for removal (#109773)
@openclaw/codex is force-updated with core, so string plan steps can only
reach the normalizer from a plugin pinned against an update. Record that
as a TODO instead of a standing version-skew contract.
2026-07-17 10:11:10 +01:00
krissding 4612b1692c fix: guard terminateStaleProcessesSync against non-ESRCH kill errors (#109702)
* fix: guard terminateStaleProcessesSync against non-ESRCH kill errors

The two catch blocks silently swallowed all errors, not just ESRCH.
Non-ESRCH errors (e.g. EPERM) indicate the process is still alive but
cannot be signaled — continuing as if it were killed risks leaving a
stale process on the port.

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

* fix: continue stale PID cleanup after signal errors

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

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-17 10:06:37 +01:00
Peter Steinberger 8ff4f0161f refactor(push-web): split legacy JSON parsing out of the doctor migration
7af9358841 (#109609) pushed state-migrations.web-push.ts past the
max-lines limit (709), failing check-lint repo-wide. Extract the pure
parsing layer (legacy subscriptions/VAPID JSON -> validated shapes) into
state-migrations.web-push-parse.ts; the migration module keeps
detection/claiming/DB import. No behavior change; 23/23 module tests
green.
2026-07-17 02:03:50 -07:00
krissding af469c85cf fix(cli): guard secrets plan JSON.parse against malformed input (#109721)
* fix(cli): guard secrets plan JSON.parse against malformed input

readPlanFile reads a user-specified file and parses it with JSON.parse
without a try-catch. A malformed or corrupted plan file produces a raw
SyntaxError that is not user-actionable.

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

* test: tighten malformed secrets plan proof

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

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-17 10:00:35 +01:00
Wynne668 07a36f6eda fix(config): preserve Unicode in validation received values (#109664)
* fix(config): preserve Unicode in validation received values

* test: tighten config diagnostic truncation proof

Co-authored-by: ZengWen-DT <ceng.wen@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-17 01:53:19 -07:00
mushuiyu886 7af9358841 fix(push-web): ignore blank VAPID environment overrides (#109609)
* fix(push-web): ignore blank VAPID environment values

* fix: normalize migrated web push VAPID inputs

Co-authored-by: mushuiyu886 <yang.haoyu@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-17 01:48:55 -07:00
Peter Steinberger 92e5a10f1a fix(doctor): diagnose ignored web fetch proxy settings (#109778)
* fix(doctor): diagnose direct web fetch proxy routing

* test(doctor): cover proxy diagnostic through public API

* test(doctor): validate emitted proxy diagnostic type
2026-07-17 01:24:32 -07:00
Peter Steinberger edcf3131ad test(gateway): stop background plugin reloads from wiping test task runtimes (#109801)
Root cause of the flaky 120s timeout in "logs a swallowed finalize error
without blocking the background run" (CI run 29559328261, shard
agentic-gateway-methods): the preceding ACP plugin-subagent test registers a
subagent run whose completion keeps running in the background after the test
ends. That leaked chain (completeSubagentRunAttempt ->
emitSubagentEndedHookForRun -> ensureSubagentRegistryPluginRuntimeLoaded ->
ensureRuntimePluginsLoaded -> loadOpenClawPlugins) starts by calling
clearActivatedPluginRuntimeState(), which clears the process-wide detached
task lifecycle runtime registration. When it lands between the next test's
setDetachedTaskLifecycleRuntime(spy) install and that test's background
finalize, finalizeTaskRunByRunId re-reads the registration at call time,
falls back to the default executor, and finalizes the run successfully - so
the finalize spy is never called while the run itself completes with an ok
frame.

The prior event-driven rework (#109653, 883995f08d) could not fix this: it
only waits longer for a spy call that never comes. The older 2s
waitForAssertion flake ("expected 1 call, got 0") was the same mechanism.

Fix at the harness boundary: gateway agent handler tests now pin the
subagent-registry deps with a no-op ensureRuntimePluginsLoaded (matching
subagent-registry's own suites), applied at harness setup, in the shared
afterEach, and through the one wholesale deps override, so no leaked
ended-run hook can reload the plugin runtime and clear a later test's
runtime seam mid-test.

Proof:
- Deterministic repro (temporary env-gated interleaving patch in
  subagent-registry.ts, not committed): hold the ACP plugin-child run's
  ended-hook load until the next finalize-only runtime registration appears,
  then reload synchronously. Pre-fix this reproduces the exact CI failure
  (target times out at 120000ms; registration observed ABSENT right after
  the reload). Post-fix, with the identical forced interleaving, all 238
  tests pass and the registration stays present.
- Stress post-fix: 10x agent.test.ts and 5x src/gateway/server-methods with
  OPENCLAW_VITEST_MAX_WORKERS=6 - 0 failures (3765 tests per shard run).
- The same wipe-then-re-register window exists in prod plugin activation
  (loadOpenClawPlugins cache-miss path); flagged separately for an
  owner-reviewed atomic-swap follow-up rather than bundled here.
2026-07-17 01:16:34 -07:00
Peter Steinberger 4ecd85e0b7 fix: keep healthy channel accounts running when one credential fails (#109766)
* fix(secrets): isolate channel account credentials

* fix(secrets): normalize Feishu default ownership

* fix(feishu): preserve accountless secret ownership

* fix(matrix): keep accountless top-level refs active
2026-07-17 01:12:18 -07:00
Peter Steinberger e693d279b3 fix: Bedrock ARN region routing, Copilot device-flow pacing, TUI input fixes (#109740)
* build(deps): bump terminal UI library to 0.80.9

* fix(plugins): Bedrock ARN region routing, stop-reason detail, and Copilot device-flow pacing
2026-07-17 01:09:29 -07:00
Peter Steinberger 6ac15970a7 feat(onboarding): unified empty-state with provider icons, websites, and recommended installs (#109681)
* feat(onboarding): unify setup recommendations

* fix(control-ui): proxy model setup icons

* fix(onboarding): refresh landing artifacts

* chore(ui): sync translated i18n catalogs

* chore(ui): keep generated locale artifacts on the refresh workflow
2026-07-17 01:01:06 -07:00
Peter Steinberger 543244e7bb perf(ci): remove the anthropic-cli jiti stall and stripe the full-plan whales (#109769)
* perf(sdk): load Claude CLI identity from a narrow plugin artifact

src/plugin-sdk/anthropic-cli.ts snapshots CLAUDE_CLI_BACKEND_ID at module
scope through the sync facade loader, which jiti-evaluates the full
anthropic api.js barrel on source checkouts: 130.86s of self time per
cold worker on CI (Testbox import profile), silently stalling every job
whose graph reaches cli-runner/prepare.ts. A narrow cli-api.js artifact
carries the two static facts; Testbox proof: the reliability+helpers
agents-core pair drops from 157.6s to 14.3s.

* perf(ci): stripe unit-fast and tooling node tests on the full plan

core-fast ran the import-bound unit-fast graph as one job (247s vitest,
181s module evaluation) and core-tooling as one serial job (241s); both
now stripe on the full plan like the compact plan, so the compact-only
expansion is deleted and the docker helper config rides with the
isolated shard on both plans. Group hints refreshed from main run
29551077288; stale per-file commands hints dropped (the consolidation
landed); cache-writer selection and the warm workflow track the stripe
names.

* fix(state): tolerate vanished sqlite sidecars in agent-db permission sweep

existsSync+chmodSync raced SQLite's own WAL/SHM cleanup: a checkpoint or
close between the two calls throws ENOENT (observed from the transcript
reconcile worker in server-startup-web-fetch-bind on CI). chmod directly
and swallow only ENOENT, which removes the TOCTOU window.
2026-07-17 00:58:32 -07:00
Peter Steinberger 0e792b6de3 refactor(channels): centralize inbound orchestration and remove internal compat (#109716)
* refactor(channels): centralize inbound turn orchestration

* refactor(runtime): remove stale compatibility paths

* chore(guards): reject internal deprecated API use

* refactor(channels): simplify core turn planning

* chore(guards): keep deprecated checks boundary-focused

* refactor(memory): keep modern config off compat barrel

* fix(msteams): preserve feedback learning

* test(channels): align modern inbound fixtures

* refactor(channels): finish modern inbound migration

* refactor(channels): tighten core inbound kernel

* fix(channels): preserve turn assembly narrowing

* test(sdk): keep runtime mock binding immutable

* test(matrix): isolate read policy runtime

* test(msteams): mock canonical reply factory

* test(slack): mock core inbound turn dispatch

* test(telegram): inject core session recorder

* test(signal): inject core session recorder

* test(googlechat): assert canonical inbound routing

* test(synology-chat): align core turn fixture

* fix(sdk): preserve direct DM runtime compat

* refactor(channels): own inbound envelope compat in core

* refactor(channels): trim inbound dispatch seams

* refactor(channels): remove redundant async wrappers

* test(synology-chat): type canonical dispatcher mock

* refactor(channels): remove remaining dead compat seams

* chore(sdk): refresh API baseline after rebase

* fix(channels): preserve direct DM identity metadata
2026-07-17 00:56:46 -07:00
Peter Steinberger 765bb37364 feat(setup): stream provider prepare progress to every surface (#109764)
* feat: stream provider preparation progress

* fix(android): refresh gateway method constants
2026-07-17 00:55:04 -07:00
Trevor Malone b8d43ea49a fix(config): strip obsolete memorySearch keys before schema validation (#68664) (#68685)
* fix(config): strip obsolete memorySearch keys from defaults and list (#68664)

* fix(config): preserve canonical memory migration precedence

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-17 00:43:14 -07:00
Peter Steinberger f095549d1d perf(agents): cut CLI runner reliability import cost (#109772) 2026-07-17 00:41:00 -07:00
Peter Steinberger d26951ae9a fix(secrets): degrade stale auth profile refs on startup (#77213)
* fix(secrets): isolate unavailable auth profile refs

Co-authored-by: Val Alexander <68980965+BunsDev@users.noreply.github.com>

* fix(secrets): retain current auth profile metadata

Co-authored-by: Val Alexander <68980965+BunsDev@users.noreply.github.com>

* style(auth): use explicit materialized fields

Co-authored-by: Val Alexander <68980965+BunsDev@users.noreply.github.com>

* fix(secrets): scrub skipped auth profile material

Co-authored-by: Val Alexander <68980965+BunsDev@users.noreply.github.com>

* test(auth): separate setup fallback from secret refs

Co-authored-by: Val Alexander <68980965+BunsDev@users.noreply.github.com>

* fix(secrets): reuse prepared auth alias metadata

Co-authored-by: Val Alexander <68980965+BunsDev@users.noreply.github.com>

---------

Co-authored-by: Val Alexander <68980965+BunsDev@users.noreply.github.com>
2026-07-17 00:38:35 -07:00
Peter Steinberger 2b18ef7426 feat(codex): surface native questions and goals (#109724)
* feat(codex): bridge native questions and goals

Co-authored-by: EVA <eva@100yen.org>

* fix(ui): preserve native question text encoding

* fix(codex): keep secret answers off action paths

* fix(codex): validate native action keys exactly

* fix(codex): isolate new goals and free-form answers

* style(codex): satisfy extension lint

* fix(codex): keep goal replacement non-destructive

* fix(codex): separate native goals from continuation

* fix(codex): preserve exact native answer labels

* test(codex): assert goal continuation stays disabled

* fix(codex): remove unused bridge exports

* test(codex): refresh goal feature snapshots

---------

Co-authored-by: EVA <eva@100yen.org>
2026-07-17 00:35:39 -07:00
ooiuuii 6651813bd0 fix(logging): redact auth-style HTTP headers (#107999)
* fix(logging): redact auth-style HTTP headers

* fix(logging): redact structured auth headers

* test(logging): keep auth fixtures synthetic

* test(logging): preserve existing gateway fixtures

* fix(logging): cover serialized auth credentials

* fix(logging): harden auth header redaction

* fix(logging): cover serialized auth whitespace

* chore(logging): refresh reviewed PR head

* test(logging): expect complete API key redaction

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-17 00:25:15 -07:00
tanshanshan 473dfc2e51 fix(compaction): add circuit breaker to stop token burn when summarizer unavailable (#86900)
* fix(compaction): stop repeated staged fallbacks

Co-authored-by: tanshanshan <tan.shanshan@xydigit.com>

* fix(compaction): preserve degraded summary state

* refactor(compaction): keep result state internal

* fix(compaction): cancel incomplete circuit-open runs

* chore: refresh PR checks

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-17 00:18:33 -07:00
Yiğit ERDOĞAN e228a3ca3a fix: gateway.cmd launcher garbles non-ASCII profile paths on non-CJK Windows locales (#108967)
* fix(daemon): encode Windows cmd launcher to the console OEM code page

* fix(infra): unexport resolveWindowsSystemEncoding

The launcher encoder now resolves the boot-time OEM code page via
resolveWindowsOemEncoding, leaving resolveWindowsSystemEncoding with no
external importers; the dead-export ratchet (knip all-exports) fails CI
on exported-but-module-local functions.

* test(windows): cover OEM launcher encoding resolver

* fix(windows): declare launcher OEM code page

* fix(windows): fail closed on unsupported OEM pages

* fix(windows): reject CP1258 precomposition drift

* fix(windows): guard CP864 launcher syntax

* test(windows): pin OEM launcher code page

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-17 00:16:59 -07:00
Peter Steinberger b64242a4a9 fix(cron): isolate unavailable webhook secret (#109739) 2026-07-17 00:10:45 -07:00
Peter Steinberger a2ec3f6904 refactor: separate external conversations from local sessions (#109411)
* feat: separate external conversations from sessions

* test: cover conversation tool authorization

* chore: refresh session schema baseline

* fix: persist effective conversation delivery text

* fix: bind conversation identity to delivery target

* fix: preserve pending conversation deliveries

* fix: make conversation delivery outcomes synchronous

* refactor: make conversation delivery durable

* fix: harden durable conversation retries

* fix: close durable conversation pre-send gaps

* fix: terminally reject invalid conversation deliveries

* refactor: route external conversations through gateway

* fix: namespace conversation delivery queue intents

* refactor: remove obsolete transcript replacement path

* test: prove conversation delivery v10 migration

* test: keep conversation action mock typed

* fix: clear conversation refactor CI gates

* test: align Reef delivery coverage

* chore: refresh Android conversation strings

* fix: harden external conversation state

* fix: close conversation race edges

* fix: preserve conversation delivery identity

* fix: replay durable conversation operations

* fix: unify agent schema at version 11

* chore: move release note context to PR

* fix: make required queue persistence force core delivery

* chore: refresh plugin SDK baseline
2026-07-17 00:09:51 -07:00
Peter Steinberger b84199644d fix: silent credential-save failures and session/tool hygiene gaps (#109622)
* fix(agents): surface auth persistence failures and harden session, model, and shell tool hygiene

* refactor(agents): keep shell invocation types module-local

* test(agents): derive shell config type locally
2026-07-17 00:02:45 -07:00
Peter Steinberger 007d50f6ff test(commands): pin session freshness fixtures away from the daily-reset boundary (#109705) 2026-07-17 00:01:16 -07:00
Chris 35fa1f9613 fix(reply): resolve abort response prefix context (#45315)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-17 00:00:50 -07:00
Peter Steinberger 44569ffdda fix(agents): prevent stale replies after transcript rewrites (#109676)
* fix(agents): scope final replies to current run

Co-authored-by: ZengWen-DT <ceng.wen@xydigit.com>

* refactor(agents): internalize attempt helper

* fix(agents): preserve yielded turn classification

* fix(agents): preserve yielded run ownership

---------

Co-authored-by: ZengWen-DT <ceng.wen@xydigit.com>
2026-07-16 23:58:43 -07:00
Abner Shang a33ddc9dc5 fix(openai): close OAuth callback prompts cleanly (#89491)
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 23:58:41 -07:00
Peter Steinberger c13925b387 fix(webhooks): keep routes cold when SecretRefs are unavailable (#109715)
* fix(webhooks): isolate unresolved route secrets

* chore(plugin-sdk): refresh API baseline

* docs(secrets): refresh credential surface
2026-07-16 23:56:59 -07:00
Peter Steinberger a838c68dbe feat(talk): add Gemini Live video (#109719)
Stream bounded browser camera frames directly to Gemini Live and keep camera media off the Gateway. Add lifecycle, function-calling, fake-camera E2E, and live-smoke coverage.

Co-authored-by: shushushu <1064076525@qq.com>
2026-07-16 23:55:06 -07:00
Peter Steinberger 21388da3aa perf(test): poll subagent lifecycle state faster (#109722) 2026-07-16 23:54:54 -07:00
Peter Steinberger 0097363c69 fix(secrets): keep gateway alive when web provider refs fail (#109687)
* fix(secrets): isolate unavailable web providers

* fix(secrets): keep web result type internal

* fix(secrets): hide unavailable web selections
2026-07-16 23:48:37 -07:00
Peter Steinberger 2030ac7438 fix(acp): preserve legacy replay state during doctor repair (#109685)
* fix(acp): move legacy replay migration to doctor

* refactor(acp): use Kysely for replay migration

* style(acp): remove redundant replay coercions

* style(acp): format replay migration
2026-07-16 23:29:29 -07:00
Peter Steinberger fb946267ae perf(test): poll gateway startup state faster (#109714) 2026-07-16 23:28:20 -07:00
Peter Steinberger f0aa2c892f refactor(tui): unify local queue fallback admission (#109706) 2026-07-16 23:16:11 -07:00
Peter Steinberger 03d287d111 fix: Responses streams mishandle interleaved output items and silent truncation (#109615)
* fix(ai): track Responses output items per index and require terminal stream events

* test(ai): add live Responses stream coverage

* test(infra): mirror packages live glob in live-config test
2026-07-16 23:15:35 -07:00
Masato Hoshino 45ab24dac4 fix: queued MEDIA attachments survive delivery retries (#108969)
* fix: queued MEDIA attachments survive delivery retries

Local media carried in a legacy MEDIA: text directive was invisible to
queue staging (which reads only structured mediaUrl(s)), so the raw
directive was persisted with no queue-owned copy and a retry read the
already-deleted producer path — burning the retry budget and dropping the
attachment plus its text.

Project each source payload's effective media through the canonical
createOutboundPayloadPlan before staging and fold directive-derived local
sources into the queue copy's structured fields, so the existing spool
takes custody. The custody copy anchors both mediaUrl and mediaUrls to the
effective set so the staged copy overrides the preserved in-text directive
on replay; the rendered-batch plan is recomputed from the deduplicated
effective media to avoid count inflation. Raw pre-hook text, the copy-free
live send, the same media capability, and sensitive-media fail-closed are
all unchanged. No schema/config/TTL change.

Extends the ownership invariant from #108501 / #108502 to the legacy
MEDIA: text-directive carrier.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* refactor(outbound): localize queue media custody

Trim the direct helper matrix in favor of end-to-end queue recovery proof.

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

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 23:15:08 -07:00
Yuval Dinodia 73cf9a8bed fix(plugins): plugins.deny is bypassed by a mixed-case manifest id (#109237)
* fix(plugins): canonicalize manifest plugin ids to lowercase

Plugin config policy lists (plugins.deny, plugins.allow, plugins.entries)
are lowercase-normalized through normalizePluginId, but a plugin's
self-declared manifest id was only trimmed, never lowercased. A plugin
publishing "id": "Malicious-Scraper" therefore never matched an operator
denylist entry of "malicious-scraper" and fell through to default
activation, loading its hooks, channels, secret integrations, and tools.
The same gap let a mixed-case spelling evade the core reserved-id check.

Canonicalize the id at the manifest parse boundary where
PluginManifestRecord.id is minted, so every downstream policy consumer
compares against the same canonical form.

* test(plugins): prove mixed-case deny at gateway startup

* test(plugins): assert denied gateway record is absent

* test(plugins): materialize allowed secret fixture

* fix(plugins): compare a derived policy key instead of rewriting manifest identity

Manifest ids stay exactly as declared. Deny, allow, and per-entry checks now
compare a lowercase policy key derived at each enforcement boundary, matching
the lowercase-normalized config lists.

The previous approach lowercased PluginManifestRecord.id at the parse boundary.
That id is also matched against the plugin runtime export id, and a mismatch is
a hard load failure, so an existing plugin declaring the same mixed-case id in
both its manifest and its runtime export would stop loading after upgrade.

The Gateway fixture now declares a mixed-case manifest id with a matching
mixed-case runtime export, covering that upgrade case, and drops the allowlist
that previously scoped discovery by a lowercase id and masked the denylist
behavior under test.

* fix(plugins): close mixed-case policy gaps

* test(plugins): use tracked policy fixture temp dir

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 23:13:13 -07:00
Peter Steinberger c63184ee9a fix(acp): persist failed bound turns so transcripts match the channel (#109683)
* fix(acp): persist failed bound turns so transcripts match the channel

A bound ACP turn that failed delivered an error reply to the channel but
wrote nothing to the session transcript: persistAcpDispatchTranscript ran
only on the success path, and turnPromptText was block-scoped inside the
try so the catch could not reach it. The bound transcript then silently
diverged from what the user saw, and the next turn resumed from history
that never mentioned the failure. Persist failures were also swallowed at
verbose level.

Persist exactly once, after the turn's outcome settles:
- success writes after finalization, so a finalizer failure is no longer
  recorded as a clean success;
- failures record the streamed output ahead of the error text, snapshotted
  before delivery so the accumulator cannot fold the error in twice;
- a dispatch flag (not prompt-text truthiness) gates the failure write, so
  attachment-only turns are covered and pre-dispatch setup failures do not
  mint blank-prompt records.

Found while live-testing the ACP connectors: codex and gemini bind lanes
pass 5/5, claude times out with turns that complete but never appear in the
bound transcript. This fixes the silent-divergence class and makes that
failure observable; the claude-specific trigger is tracked separately.

* fix(acp): narrow acp resolution before reading meta in the shared persist helper
2026-07-16 23:12:58 -07:00
Peter Steinberger c742caee4b perf(agents): prime code mode with compact tool ids (#109651) 2026-07-16 23:09:03 -07:00
Peter Steinberger c80b236a09 fix: local chat honors queue steering (#109689)
* fix(tui): honor local queue steering

* fix(tui): narrow pending collect queue

* test(tui): validate collected call safely

* test(tui): emit local steering evidence
2026-07-16 23:03:27 -07:00
Monkey-wusky a8fd558d62 fix(docs): cancel non-OK search response body before throwing (#109508)
When the Cloudflare docs search API returns a non-OK status,
fetchDocsSearch threw without cancelling the response body.
This could leave the underlying connection open until GC.

Cancel the body before throwing, matching the pattern established
in reef guard adapters (#109196) and fetchOpenRouterModels.
2026-07-16 22:58:13 -07:00
pick-cat f4f5150557 fix(video-generation): DashScope downloads hang when CDN body stalls after headers (#109394)
* fix(video-generation): bound stalled DashScope download body reads

* test(video-generation): narrow DashScope download asset for tsgo

* test(video-generation): narrow optional DashScope video buffer for tsgo

* test(video-generation): bind DashScope buffer before tsgo asserts

* fix(video-generation): fail closed on exhausted DashScope download budget

When the operation deadline passes a function that returns 0, the
previous resolver gate (resolved > 0) dropped the exhausted budget
and fell back to the 120s default. Also, readResponseWithLimit skips
chunk idle timeout when chunkTimeoutMs is 0/falsy, so a zero budget
would read the body unbounded instead of failing fast.

Now the resolver preserves zero/negative values and the body stage
throws immediately when the remaining budget is exhausted.

Co-Authored-By: nebulacoder-v8.0 <noreply@zte.com.cn>

* fix(video-generation): reject exhausted download deadline before fetch

Check the resolved download timeout before fetchWithTimeoutGuarded so an
already-exhausted operation does not initiate network I/O. Previously the
deadline guard ran after headers, which still sent bytes over the wire.

Co-Authored-By: nebulacoder-v8.0 <noreply@zte.com.cn>

* fix(video-generation): release failed DashScope downloads

---------

Co-authored-by: nebulacoder-v8.0 <noreply@zte.com.cn>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-16 22:54:41 -07:00
Leon-SK668 f977649065 fix(auto-reply): preserve emoji in bash session snippets (#109468) 2026-07-16 22:43:40 -07:00
Peter Steinberger 630b16805c fix(providers): refresh zai/kimi/moonshot/xai catalogs against July 2026 vendor docs (#109666)
* fix(providers): refresh vendor catalogs and setup hints

* test(providers): align registration metadata expectations
2026-07-16 22:41:03 -07:00
Peter Steinberger 399345e1bb feat: report Pi and OpenCode in guided setup (#109624)
* feat(onboarding): detect Pi and OpenCode CLIs

* fix(onboarding): clarify Pi and OpenCode readiness
2026-07-16 22:35:33 -07:00