* feat(ui): composer capability menu with per-session overrides
* refactor(ui): keep chat render within lint ceiling
* fix(ui): preserve loaded capability overrides
* fix(ui): remove stale capability menu field
* fix(ui): gate capability menu on runtime-config readiness
* fix(synology-chat): stop fabricating send message ids
The incoming-webhook send contract acks with a bare boolean and carries
no platform message id, but the adapter returned a synthetic
`sc-${Date.now()}` id and stamped it into the delivery receipt. Return
the established empty-id sentinel and an empty receipt instead, matching
the honest no-platform-id shape used by sibling channels (qqbot,
googlechat) and the plugin-sdk empty-id contract.
Co-Authored-By: Claude <noreply@anthropic.com>
* test(synology-chat): verify truthful webhook receipts
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
The spawned agent child process in createAcpClient had no error
listener. If the agent binary failed to start, the error event
would be unhandled and could crash the process.
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
The react message-action handler dispatched straight to the sender without
checking the resolved account, so a disabled Nextcloud Talk account
(`enabled:false`) that still had a baseUrl/botSecret in config could keep
emitting reactions. `describeMessageTool` already hides the tool for
unconfigured accounts, but an explicit accountId can reach `handleAction`
directly. Enforce the same enabled+configured gate at dispatch, mirroring
the Signal reaction fix (#112607).
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(terminal-core): prevent $ pattern injection in replaceHomePath
The second argument of String.prototype.replace() interprets $ sequences
as special replacement patterns ($&, $`, $', $1-$9, $<name>). When the
user home directory path contains $ followed by special characters, the
replacement produces a corrupted path in the display string.
Using a replacer function (() => fallbackHome) instead of the raw string
argument prevents $ pattern interpretation, ensuring the literal home
directory path is used regardless of its content.
* test(terminal-core): cover literal dollar home paths
---------
Co-authored-by: lizeyu-xydt <li.zeyu@xydigit.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(codex): restore connected apps for token-authenticated runs
* fix(codex): keep app inventory protocol types private
* fix(codex): align native runtime with Codex 0.146.0
Co-authored-by: Steven Lee <stevenlee@openai.com>
* fix(codex): clean up latest app-server integration
Co-authored-by: Steven Lee <stevenlee@openai.com>
* fix(codex): keep internal protocol types private
* fix(ci): repair current main Codex landing gates
* fix(ci): format inherited code mode matrix
* fix(codex): reconcile native app-server contracts with main
Prepare a verified GitHub-hosted mainline merge while preserving the reviewed Codex 0.146.0 fixes and canonical OpenAI authentication.
Co-authored-by: Steven Lee <stevenlee@openai.com>
* fix(codex): keep QA evidence in its owning plugin
Resolve the current-main Code Mode test rename without resurrecting the retired core test path.
Co-authored-by: Steven Lee <stevenlee@openai.com>
* fix(codex): enforce canonical OpenAI app-server auth
Reject retired provider aliases without runtime compatibility, direct operators to the doctor migration, and remove the redundant OpenAI API-key predicate.
Co-authored-by: Steven Lee <stevenlee@openai.com>
* chore(codex): reconcile latest main dependency graph
Preserve current main dependency changes while preparing the original Codex PR for an ancestry-preserving signed mainline merge.
Co-authored-by: Steven Lee <stevenlee@openai.com>
* fix(codex): unify bundled Codex 0.146 runtimes
Keep the ACP adapter on the same 0.146.0 Codex release as the managed runtime, remove obsolete 0.145.0 platform artifacts and unused semver compatibility, and preserve the latest main dependency upgrades.
Co-authored-by: Steven Lee <stevenlee@openai.com>
---------
Co-authored-by: Peter Steinberger <peter@steipete.me>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(msteams): keep file replies in channel threads
* fix(msteams): keep SharePoint files in channel threads
Fixes#88836 by forwarding channel thread roots through the existing Microsoft Teams proactive activity boundary while preserving top-level, group chat, and personal delivery.
Co-authored-by: Jasmine Zhang <jasminezhang@JasminedeMac-mini.local>
* test(msteams): use lint-safe real SDK HTTP capture
---------
Co-authored-by: Jasmine Zhang <jasminezhang@JasminedeMac-mini.local>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(telegram): linkPreview:false is ignored on streamed replies
Replies delivered through draft streaming still unfurled the first URL
even with channels.telegram.linkPreview: false. Non-streamed sends
already honored the flag.
createTelegramDraftStream never received linkPreview and never set
link_preview_options, on either its initial sendMessage or its
editMessageText calls. Finalization could not clean it up: it skips the
final edit when the streamed draft text already equals the final text,
which is the common case, so the draft message stays as-is with the
preview attached.
Passes linkPreview from telegramCfg into the draft stream and applies
link_preview_options: { is_disabled: true } on the send and on every
edit, since an edit that omits the field re-enables the preview
server-side. Rich messages keep expressing this as skip_entity_detection
at render time, which already worked.
Call arity is preserved when no preview options apply, so existing edit
assertions are unaffected.
Closes#111525
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* test(telegram): cover streamed reply option parity
Co-authored-by: Zakaria Rahali <zakariarahali288@gmail.com>
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix(protocol): make Swift drift checks non-mutating
* test(protocol): cover core Swift gateway frames
* docs(protocol): clarify Swift model update flow
Fixes#106910.
Preserve the contributor design from #107000 while updating both the normal and current compaction owner paths.
Co-authored-by: Sebastien Tardif <sebtardif@ncf.ca>
* fix(sandbox): safely repair sandbox workspace state
Fixes#111661. Repair active agent, shared, session, and global sandbox workspace state through the existing canonical SQLite registry without importing inactive or unrelated agent state.
Preserves and builds on the original sandbox doctor migration and regression from #111812.
Co-authored-by: TianT1209 <55179364+TianT1209@users.noreply.github.com>
* fix(sandbox): isolate doctor sandbox state by profile
Resolve exact sandbox scope ownership from the state directory requested by doctor, not ambient process state, and cover cross-profile SQLite registry isolation.
Co-authored-by: TianT1209 <55179364+TianT1209@users.noreply.github.com>
* test(sandbox): preserve typed workspace ownership proof
Keep exact inactive and active sandbox fixture paths non-optional under the repository core-test typecheck.
Co-authored-by: TianT1209 <55179364+TianT1209@users.noreply.github.com>
* fix(sandbox): ignore stale non-session workspace scopes
Validate canonical registered session ownership before Doctor migrates sandbox workspace state; preserve exact profile isolation and leave the existing registry untouched.
Co-authored-by: TianT1209 <55179364+TianT1209@users.noreply.github.com>
* fix(doctor): derive sandbox ownership from durable sessions
Read the existing agent-owned SQLite session store without opening writable handles. Repair pruned, global and unscoped sandbox workspaces and resolve omitted sandbox roots from the selected state profile. Retire the transient runtime registry reader.
Co-authored-by: TianT1209 <55179364+TianT1209@users.noreply.github.com>
* test(doctor): derive overlap workspace from agent owner
Honor current main workspace-qualified sandbox scope contract when proving non-default agent ownership in hosted CI.
Co-authored-by: TianT1209 <55179364+TianT1209@users.noreply.github.com>
---------
Co-authored-by: TianT1209 <55179364+TianT1209@users.noreply.github.com>
* refactor(ui): dissolve the General settings page into Appearance
* test(ui): drop dissolved config route expectation
* test(ui): cover legacy General model redirect
* style(ui): format legacy redirect test
Apply the shared, surrogate-safe outbound chunker to the existing Nostr text limit so the real delivery planner produces ordered NIP-04 events. Preserve assistant-visible sanitization and prove short, word, newline, hard-split, and odd-prefix Unicode boundaries.
Co-authored-by: liyuanbin <li.yuanbin1@xydigit.com>