- Prevent Control UI session render crashes when `marked.parse()` encounters pathological recursive markdown by safely falling back to escaped `<pre>` output.
- Tighten markdown fallback regression coverage and keep changelog attribution in sync for this crash-hardening path.
Co-authored-by: Bin Deng <dengbin@romangic.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
- Feishu/group slash command detection: normalize group mention wrappers before command-authorization probing so mention-prefixed commands are recognized in group routing.\n- Source PR: #36011\n- Contributor: @liuxiaopai-ai\n\nCo-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>\nCo-authored-by: liuxiaopai-ai <73659136+liuxiaopai-ai@users.noreply.github.com>
## Summary\n\nFeishu group slash command parsing is fixed for mentions and command probes across authorization paths.\n\nThis includes:\n- Normalizing bot mention text in group context for reliable slash detection in message parsing.\n- Adding command-probe normalization for group slash invocations.\n\nCo-authored-by: Sid Qin <sidqin0410@gmail.com>\nCo-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
* fix(feishu): accept groupPolicy "allowall" as alias for "open"
When users configure groupPolicy: "allowall" in Feishu channel config,
the Zod schema rejects the value and the runtime policy check falls
through to the allowlist path. With an empty allowFrom array, all group
messages are silently dropped despite the intended "allow all" semantics.
Accept "allowall" at the schema level (transform to "open") and add a
runtime guard in isFeishuGroupAllowed so the value is handled even if it
bypasses schema validation.
Closes#36312
Made-with: Cursor
* Feishu: tighten allowall alias handling and coverage
---------
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
When the Feishu API hangs or responds slowly, the sendChain never settles,
causing the per-chat queue to remain in a processing state forever and
blocking all subsequent messages in that thread. This adds a 30-second
default timeout to all Feishu HTTP requests by providing a timeout-aware
httpInstance to the Lark SDK client.
Closes#36412
Co-authored-by: Ayane <wangruofei@soulapp.cn>
* fix(gateway): pass actual version to Control UI client instead of "dev"
The GatewayClient, CLI WS client, and browser Control UI all sent
"dev" as their clientVersion during handshake, making it impossible
to distinguish builds in gateway logs and health snapshots.
- GatewayClient and CLI WS client now use the resolved VERSION constant
- Control UI reads serverVersion from the bootstrap endpoint and
forwards it when connecting
- Bootstrap contract extended with serverVersion field
Closes#35209
* Gateway: fix control-ui version version-reporting consistency
* Control UI: guard deferred bootstrap connect after disconnect
* fix(ui): accept same-origin http and relative gateway URLs for client version
---------
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
Move skill-command deduplication by skillName from the Discord-only
`dedupeSkillCommandsForDiscord` into `listSkillCommandsForAgents` so
every interface (TUI, Slack, text) consistently sees a clean command
list without platform-specific workarounds.
When multiple agents share a skill with the same name the old code
emitted `github` + `github_2` and relied on Discord to collapse them.
Now `listSkillCommandsForAgents` returns only the first registration
per skillName, and the Discord-specific wrapper is removed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(agents): bypass pendingDescendantRuns guard for cron announce delivery
Standalone cron job completions were blocked from direct channel delivery
when the cron run had spawned subagents that were still registered as
pending. The pendingDescendantRuns guard exists for live orchestration
coordination and should not apply to fire-and-forget cron announce sends.
Thread the announceType through the delivery chain and skip both the
child-descendant and requester-descendant pending-run guards when the
announce originates from a cron job.
Closes#34966
* fix: ensure outbound session entry for cron announce with named agents (#32432)
Named agents may not have a session entry for their delivery target,
causing the announce flow to silently fail (delivered=false, no error).
Two fixes:
1. Call ensureOutboundSessionEntry when resolving the cron announce
session key so downstream delivery can find channel metadata.
2. Fall back to direct outbound delivery when announce delivery fails
to ensure cron output reaches the target channel.
Closes#32432
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: guard announce direct-delivery fallback against suppression leaks (#32432)
The `!delivered` fallback condition was too broad — it caught intentional
suppressions (active subagents, interim messages, SILENT_REPLY_TOKEN) in
addition to actual announce delivery failures. Add an
`announceDeliveryWasAttempted` flag so the direct-delivery fallback only
fires when `runSubagentAnnounceFlow` was actually called and failed.
Also remove the redundant `if (route)` guard in
`resolveCronAnnounceSessionKey` since `resolved` being truthy guarantees
`route` is non-null.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(cron): harden announce synthesis follow-ups
---------
Co-authored-by: scoootscooob <zhentongfan@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>