Commit Graph

16200 Commits

Author SHA1 Message Date
Peter Steinberger 08ecf63bb6 fix(deadcode): resolve strict-workspace fallout from bundled plugin roots
The strict knip workspaces landed in #108547 flagged seven files. Two are
convention-resolved and become explicit entries (discord configured-state via
the package-state probes, qa-lab cli via the SDK facade basename resolver);
the other five were dead barrels/wrappers superseded by canonical modules and
are deleted (browser bridge/cdp barrels, discord timeouts wrapper, openai
register.runtime, qa-lab model-selection wrapper).
2026-07-16 03:08:17 +01:00
Peter Steinberger d42dfed3f2 chore(codex): format usage module, fix marker import in test 2026-07-16 03:06:48 +01:00
Peter Steinberger 7864a6e6ad fix(codex): import ProviderUsageSnapshot from provider-usage 2026-07-16 03:06:47 +01:00
Peter Steinberger 7eeb1096db fix(codex): re-home app-server usage reporting on the harness seam
The deleted text provider's usage hook was the only source for the /status
Codex subscription usage line. Harnesses can now contribute an optional
usage snapshot (provider hooks keep priority; only distinct synthetic hook
owners fall through), and the codex harness reports app-server rate limits
via account/rateLimits/read with the same conversion and account identity
as before. No text provider resurrected; deadcode and SDK surface gates
clean.
2026-07-16 03:06:47 +01:00
Peter Steinberger 6bcb561012 fix(codex): repair identity-fold CI fan-out
- null-vs-undefined runtime record type at the provider-move helper
- gateway models.list fixtures expect the new agentRuntime intent field
  (codex/implicit for policy-backed OpenAI routes, openclaw/implicit for
  synthetic routes without provider policy)
- split doctor cron legacy-repair into its own module to satisfy the
  max-lines gate without suppressions; callers import directly
2026-07-16 03:06:43 +01:00
Peter Steinberger 3c8269ca52 refactor(codex)!: fold the codex text provider into openai with a doctor migration
The live codex text provider was a redundant projection of the openai
catalog (exclusive provider ownership; the openai plugin's ChatGPT OAuth
discovery already serves gpt-5.6-* route-aware). Folding it:

- extensions/codex no longer registers a text provider, catalog entry, or
  synthetic text auth; provider.ts/provider-catalog.ts/provider-discovery.ts
  and the route-blind model-name heuristics are deleted; the narrow
  post-harness reasoning fallback moves to an app-server-owned module
- openai thinking policy keys on explicit selected-route provenance
  (api === openai-chatgpt-responses) instead of value-shape inference
- models.list gains an optional additive agentRuntime field (configured
  intent); session agentHarnessId remains the execution proof
- doctor --fix migrates the shipped codex/* config shape end to end:
  every model slot, provider-config merge with blocker-aware conflict
  handling, sessions, cron payloads (two-phase: runtime policy persists
  before cron refs rewrite), transcripts; migrated refs carry model-scoped
  agentRuntime.id=codex preserving the shipped wizard semantics; auto
  runtime policies normalize to codex with sibling fields preserved;
  blocked provider conflicts retain the whole legacy namespace fail-closed
  with an actionable warning
- the stale openai:default profile cleanup (#91352) was deliberately
  deferred to a follow-up after review showed it needs per-agent identity
  proofs; doctor keeps warning about unusable profiles

Fixes #105561
Fixes #84637
Fixes #90420
2026-07-16 03:06:43 +01:00
Peter Steinberger 169ed48866 refactor(deadcode): tighten Anthropic extension roots (#108547) 2026-07-15 18:35:24 -07:00
Alix-007 dcf110756f fix(xai): apply request policy to video generation requests (#104836) 2026-07-15 21:22:46 -04:00
Peter Steinberger d4183facf1 refactor(deadcode): tighten extension root modeling (#108538) 2026-07-15 18:18:23 -07:00
yyj-xydt 9c6c8446a7 fix(zalo): harden hosted media token checks (#108512) 2026-07-15 18:10:55 -07:00
Eden bc93fe9f25 fix(line): honor channelData.line.mediaKind on the reply-token path (#106515)
* fix(line): honor channelData.line.mediaKind on the reply-token path

The reply-token delivery built every media message with createImageMessage,
ignoring channelData.line.mediaKind (and previewImageUrl/durationMs/trackingId),
so a video/audio reply was silently downgraded to a broken image. The push path
already honored mediaKind via resolveLineOutboundMedia + buildLineMediaMessageObject.

Route reply-token media through those same helpers (relocated to outbound-media.ts
and reused by both paths) via an injected buildMediaMessage dep wired in monitor.ts,
preserving the delivery file's dependency-injection boundary. Generic media without
LINE-specific options keeps the image route; a media that cannot be built surfaces
as a visible partial delivery so the text still reaches the user.

* refactor(line): unify reply media delivery

* fix(line): normalize media delivery failures

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-15 18:06:26 -07:00
NIO f66786f0cb fix(mattermost): bound websocket handshake waits at 30s (#105553)
* fix(mattermost): bound websocket handshake waits at 30s

* refactor(mattermost): prove handshake timeout wiring

* chore: refresh Mattermost CI cohort

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-15 18:01:40 -07:00
Peter Steinberger 9317aadaa2 feat(slack): add opt-in scoped presence events (#108510)
* feat(slack): add opt-in presence events

* style(slack): satisfy presence lint rules

* chore: keep release changelog centralized

* fix(slack): satisfy presence integration gates

* fix(slack): preserve eligible presence targets
2026-07-15 17:43:26 -07:00
Peter Steinberger d3dcb36895 refactor(deadcode): tighten Google and xAI extension roots (#108523) 2026-07-15 17:34:53 -07:00
Peter Steinberger b6077738b3 test: fix realtime transcription lint (#108516)
* test: fix realtime transcription lint

* test: bound realtime transcription test payloads
2026-07-15 17:29:07 -07:00
Dallin Romney 87079d025e improve(qa): consolidate live transport selector contracts (#108465)
* refactor(qa): consolidate live transport selectors

* refactor(qa): remove live transport indirection
2026-07-15 17:20:07 -07:00
NIO ed16970fc6 fix(feishu): pass timeoutMs through app-registration guarded fetch (#105549)
* fix(feishu): pass timeoutMs through app-registration guarded fetch

* refactor(feishu): keep registration timeout internal

* docs(changelog): credit Feishu timeout fix

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-15 17:18:54 -07:00
Eden 75234c68b3 fix(line): use precise control-command check for group mention bypass (#107230)
* fix(line): use precise control-command check for group mention bypass

Group requireMention bypass is gated on `command.hasControlCommand`, but LINE
fed it the broad `shouldComputeCommandAuthorized` detector, which is true for
any inline "/x"/"!x" token. An allowlisted member's plain message like
"cd /home" would satisfy the bypass and reach the agent even though the bot
was never mentioned.

Groups now use the precise `hasControlCommand` (message starts with a real
command); DMs keep the broad detector since they have no mention gate. This
mirrors googlechat's monitor-access wiring. The group/DM split lives in a
small `resolveLineControlCommand` helper in group-policy.ts, next to
resolveLineGroupRequireMention, so bot-handlers.ts stays within its size cap.

* test(line): assert group mention-bypass with a registered control command

The positive regression case sent `!status`, which the mocked
command-auth module treated as a control command via a naive
`startsWith("!")`. Production `hasControlCommand` matches the message
body against registered command aliases (e.g. `/status`), so `!status`
is only an inline token, not a real control command. The test could
therefore pass without proving that a genuine control command still
bypasses requireMention.

Use the registered `/status` alias for the bypass cases and make the
mock reflect the real split: `hasControlCommand` = starts with a
registered alias (precise); `shouldComputeCommandAuthorized` =
`hasInlineCommandTokens` regex over `/x`/`!x` (broad). The two
detectors are now distinguishable, so the group precise-detector path
is actually exercised.

* refactor(line): centralize command detection

* test(line): complete direct message fixture

* docs(changelog): credit LINE command fix

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-15 17:12:49 -07:00
Peter Steinberger 9bee0d4cb8 refactor(deadcode): tighten more provider extension roots (#108515) 2026-07-15 17:05:21 -07:00
Dallin Romney 2d9b78fff7 refactor(qa): canonicalize live scenario coverage (#108464) 2026-07-15 16:50:41 -07:00
Peter Steinberger 0763a40bea refactor(vllm): remove unused registration shim (#108500) 2026-07-15 16:36:30 -07:00
NIO b18f1a8ecd fix(tlon): clear SSE connect timeout after failed openStream (#104585)
* fix(tlon): clear SSE connect timeout after failed openStream

* refactor(tlon): scope SSE connect timeout

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-15 16:32:54 -07:00
Josh Avant 8e6f966482 fix(codex): continue turns after progress replies (#108487)
* fix(codex): defer omitted source reply finality

* test(codex): refresh source reply prompt snapshots
2026-07-15 16:27:28 -07:00
Peter Steinberger 370b80b74d refactor(deadcode): tighten provider extension roots (#108497) 2026-07-15 16:23:47 -07:00
Peter Steinberger 8aa2392003 refactor(deadcode): harden unused export coverage (#108484) 2026-07-15 15:49:30 -07:00
Peter Steinberger 555c38f483 test(qa): align live selector coverage tests (#108481) 2026-07-15 15:40:32 -07:00
Josh Avant 3b47d18cc7 fix(zalo): reject unsupported message actions early (#108434) 2026-07-15 15:29:46 -07:00
Peter Steinberger 484ad52f37 fix(qa): keep package harness off private runtime (#108476) 2026-07-15 15:23:01 -07:00
Peter Steinberger 3ee408b7b5 fix(qa): isolate Crabline from package live lanes (#108472)
* fix(qa): isolate Crabline from package live lanes

* fix(qa): narrow optional smoke runtime

* ci(release): avoid unrelated Crabline install
2026-07-15 15:09:07 -07:00
Josh Avant 2cc04c205f fix(qa-channel): bind message actions to authorized targets (#108433)
* fix(qa-channel): bind message actions to authorized targets

* fix(qa-channel): close target-binding review gaps

* fix(qa-lab): preserve conversation identity in snapshots

* fix(qa-channel): canonicalize scoped targets

* fix(qa-channel): unify target parsing

* fix(qa-channel): close review gaps
2026-07-15 14:36:20 -07:00
Peter Steinberger b624abfc69 fix(discord): stop channel presence greetings for unrelated guild members (#108448)
* fix(discord): scope presence wakes to channel viewers

* chore: remove release-owned changelog entry

* fix(discord): bound presence permission lookups

* test(discord): bind presence fetch mock

* fix(discord): keep presence lookup overflow retryable
2026-07-15 13:51:48 -07:00
Dallin Romney af71400c8e refactor(qa): route live channel selectors through suite host (#108429)
* refactor(qa): route live channel selectors through suite host

* fix(qa): repair live selector CI

* fix(qa): remove retired runner exports

* fix(qa): remove obsolete live evidence
2026-07-15 13:35:34 -07:00
Peter Steinberger 28d30e9dae ci: stabilize release validation tests (#108420)
* test(codex): remove turn-watch timing race

* ci: pin workflow sanity shellcheck

* ci: run workflow sanity on blacksmith

* ci: serialize workflow sanity lint

* ci: bound workflow lint stalls

* ci: cap actionlint process fanout

* ci: report stalled workflow shellcheck

* ci: stabilize release validation checks

* ci: restore release workflow shellcheck

* test: preserve codex turn watch reset proof
2026-07-15 13:22:31 -07:00
Peter Steinberger ff8a015981 test: tighten additional async polling (#108450) 2026-07-15 13:14:35 -07:00
Dallin Romney 77d07dc3e9 refactor(qa): migrate Telegram scenarios into QA Lab (#108430)
* refactor(qa): migrate Telegram scenarios into QA Lab

* refactor(qa): remove retired Telegram runner exports
2026-07-15 12:55:00 -07:00
Alix-007 dbbe012256 fix(feishu): bound stalled docx image URL reads (#104663)
* fix(feishu): bound stalled docx image URL reads

* fix(feishu): honor configured docx image timeout

* fix(feishu): avoid total deadline for docx images

* refactor(feishu): extract docx upload input handling

* fix(feishu): harden document image uploads

Co-authored-by: Alix-007 <li.long15@xydigit.com>

* refactor(feishu): keep docx helper types internal

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-15 12:39:17 -07:00
xingzhou 7ea249463c fix(qa): handle Matrix CLI stream errors (#102698)
Co-authored-by: Dallin Romney <dallinromney@gmail.com>
2026-07-15 12:33:35 -07:00
NIO e25f512f83 fix(browser): pass control-client timeoutMs through guarded fetch dispatcher floors (#106497)
* fix(browser): pass control-client timeoutMs through guarded fetch dispatcher floors

* test(browser): simplify control timeout forwarding coverage

---------

Co-authored-by: Colin <colin@solvely.net>
2026-07-15 15:32:37 -04:00
Peter Steinberger ff4d854167 fix(reef): migrate legacy peer trust config (#108417)
* fix(reef): migrate legacy peer trust config

* chore(reef): leave changelog to release flow

* build(reef): refresh bundled config metadata

* fix(reef): keep identity scope internal
2026-07-15 11:37:32 -07:00
Peter Steinberger b4b6afadd3 refactor(codex): split app-server thread lifecycle (#108414)
* refactor(codex): split thread lifecycle

* refactor(codex): keep lifecycle types internal
2026-07-15 11:23:47 -07:00
Peter Steinberger 023126b802 test(discord): isolate component registry runtime (#108410)
* test(discord): isolate component registry runtime

* test(discord): keep runtime reset test-local
2026-07-15 11:17:34 -07:00
zw-xysk 30d5b74825 fix(slack): mark connected status degraded without bot identity (#105556)
* fix(slack): mark connected status degraded without bot identity

When auth.test fails or botToken is a user token (user_id without bot_id),
Socket Mode can still come up. Keep connected=true for transport liveness
but publish healthState=degraded with lastError instead of advertising healthy.

Rebased onto current main; credentials revoked by operator.

* fix(slack): report degraded socket identity health

Co-authored-by: zw-xysk <zhao.wang1@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-15 11:09:22 -07:00
Peter Steinberger 163a9ab5bf refactor(telegram): split message dispatch test suite (#108377)
* refactor(telegram): split message dispatch test suite

* chore: prune stale max-lines baseline
2026-07-15 10:38:37 -07:00
zw-xysk 30c257f6b4 fix(synology-chat): bound outbound NAS response bodies to prevent Gateway OOM (#105089)
* fix(synology-chat): settle user_list overflow without hanging

Cap reads at 1 MiB with Buffer concat. On overflow, finish the promise
before destroy() — bare destroy often skips end/error and hung the test.

* fix(synology-chat): share bounded user-list reader

Co-authored-by: zw-xysk <zhao.wang1@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-15 10:38:01 -07:00
Peter Steinberger f810fb35d5 refactor(reef): centralize peer trust in SQLite (#108375)
* feat(plugin-sdk): support removing pairing requests

* refactor(reef): centralize peer trust in SQLite

* chore: defer Reef release note

* fix(reef): share runtime state across module instances

* refactor(reef): narrow trust store boundary

* test(reef): pass config to account description
2026-07-15 10:21:54 -07:00
Peter Steinberger f3adeb2ac6 fix(discord): move command deploy cache to sqlite (#108381) 2026-07-15 10:03:09 -07:00
Alix-007 851f76cb0d fix(qa-lab): prevent Telegram desktop bootstrap hangs (#108157)
* fix(qa-lab): bound Telegram installer downloads

* fix(qa-lab): stage NodeSource setup script

Co-authored-by: Alix-007 <li.long15@xydigit.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-07-15 09:57:57 -07:00
lsr911 4108bbca96 fix(openai): treat blank env API key as unconfigured in speech provider (#108212)
* fix(openai): treat blank env API key as unconfigured in speech provider

process.env.OPENAI_API_KEY set to whitespace-only (e.g. '   ') causes
isConfigured to return true, but downstream synthesis fails with an
unusable bearer token. Add ?.trim() to treat whitespace-only env keys
as missing, matching the existing normalization in the image-generation
provider (image-generation-provider.ts:347).

Fixes #108186

* test(openai): cover speech env key normalization

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

* fix(openai): normalize realtime transcription env key

* chore(ci): prune stale max-lines baseline

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: luyifan <al3060388206@gmail.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>
2026-07-15 09:43:42 -07:00
Leon-SK668 b9e399eec3 fix(active-memory): normalize legacy toggle timestamps (#103116)
* fix(active-memory): normalize legacy toggle timestamps

* test(active-memory): cover non-finite legacy timestamps
2026-07-15 09:25:35 -07:00
pick-cat d11f304519 fix(qa-channel): add timeout to qa-bus state guarded fetch (#106538)
* fix(qa-channel): add timeout to qa-bus state guarded fetch

* test(qa-channel): add executable negative control for bus-state hang

* test(qa-channel): oxfmt negative-control bus-client test

* fix(qa-channel): sync SDK facade type with getQaBusState options parameter

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

* test(qa-channel): add standalone production-path proof for bus-state timeout

Proof exercises the real getQaBusState code path against loopback
TCP peers that accept but never return HTTP headers:

- Negative control: fetchWithSsrFGuard without timeoutMs stays pending
- Positive control: getQaBusState with timeout rejects with TimeoutError
- Valid response: normal server still resolves within the timeout floor

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

* test(qa-channel): log node version and head SHA in bus-state timeout proof

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

* fix(qa-channel): drop test timeout from public Plugin SDK facade type

Keep the `timeoutMs` option internal to `getQaBusState` for test-only
short floors. The public facade callers do not need it and the SDK
surface should not expose test-only parameters.

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

* chore(qa-channel): remove standalone proof script per review

The negative, timeout, and responsive cases are already durably covered in
bus-client.test.ts. The executed live output remains in the PR body as
evidence.

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

* chore: trigger CI after rebase onto main

* chore: trigger CI after rebase onto main

* test(qa-channel): keep state timeout internal

---------

Co-authored-by: nebulacoder-v8.0 <noreply@zte.com.cn>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Peter Steinberger <peter@steipete.me>
2026-07-15 08:50:53 -07:00