* fix(telegram): preserve media download transport policy
* refactor(telegram): thread media transport policy
* fix(telegram): sync fallback media policy
* fix: note telegram media transport fix (#44639)
Add shared native chat handling for /new, /reset, and /clear.
This also aligns main session key handling in the shared chat UI and includes follow-up test and CI fixes needed to keep the branch mergeable.
Co-authored-by: Nachx639 <71144023+Nachx639@users.noreply.github.com>
Co-authored-by: Luke <92253590+ImLukeF@users.noreply.github.com>
On macOS, launchctl bootout permanently unloads the LaunchAgent plist.
Even with KeepAlive: true, launchd cannot respawn a service whose plist
has been removed from its registry. This left users with a dead gateway
requiring manual 'openclaw gateway install' to recover.
Affected trigger paths:
- openclaw gateway restart from an agent session (#43311)
- SIGTERM on config reload (#43406)
- Gateway self-restart via SIGTERM (#43035)
- Hot reload on channel config change (#43049)
Switch restartLaunchAgent() to launchctl kickstart -k, which force-kills
and restarts the service without unloading the plist. When the restart
originates from inside the launchd-managed process tree, delegate to a
new detached handoff helper (launchd-restart-handoff.ts) to avoid the
caller being killed mid-command. Self-restart paths in process-respawn.ts
now schedule the detached start-after-exit handoff before exiting instead
of relying on exit/KeepAlive timing.
Fixes#43311, #43406, #43035, #43049
* fix(acp): implicit streamToParent for mode=run without thread
When spawning ACP sessions with mode=run and no thread binding,
automatically route output to parent session instead of Discord.
This enables agent-to-agent supervision patterns where the spawning
agent wants results returned programmatically, not posted as chat.
The change makes sessions_spawn with runtime=acp and thread=false
behave like direct acpx invocation - output goes to the spawning
session, not to Discord.
Fixes the issue where mode=run without thread still posted to Discord
because hasDeliveryTarget was true when called from a Discord context.
* fix: use resolved spawnMode instead of params.mode
Move implicit streamToParent check to after resolveSpawnMode so that
both explicit mode="run" and omitted mode (which defaults to "run"
when thread is false) correctly trigger parent routing.
This fixes the issue where callers that rely on default mode selection
would not get the intended parent streaming behavior.
* fix: tighten implicit ACP parent relay gating (#42404) (thanks @davidguttman)
---------
Co-authored-by: Onur Solmaz <2453968+osolmaz@users.noreply.github.com>
On macOS, launchd sets XPC_SERVICE_NAME on managed processes but does
not set LAUNCH_JOB_LABEL or LAUNCH_JOB_NAME. Without checking
XPC_SERVICE_NAME, isLikelySupervisedProcess() returns false for
launchd-managed gateways, causing restartGatewayProcessWithFreshPid()
to fork a detached child instead of returning "supervised". The
detached child holds the gateway lock while launchd simultaneously
respawns the original process (KeepAlive=true), leading to an infinite
lock-timeout / restart loop.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>