Fail closed when managed OpenAI OAuth refresh fails instead of silently falling back to stale external Codex CLI credentials.
Make managed provider OAuth authoritative after bootstrap, preserve API-key and non-OpenAI external CLI behavior, and surface targeted re-auth guidance without exposing profile IDs in group/channel replies.
Fixes#99120.
Co-authored-by: Eva <239388517+100yenadmin@users.noreply.github.com>
* fix(interactive): preserve button command values in fallback text for degraded approval UX
* fix(interactive): keep callback values private in fallback text and narrow Feishu interactive detection
- P1: Skip rendering action.type === "callback" values in
renderMessagePresentationFallbackText to avoid leaking opaque
channel/plugin data into user-visible text. Command and legacy
values are still rendered.
- P2: Replace hasMessagePresentationBlocks/hasInteractiveReplyBlocks
with isMessagePresentationInteractiveBlock so Feishu comment
guidance only appears when the presentation actually contains
buttons or selects, not for text-only blocks.
- Update tests: callback button now shows label-only; all 137 tests pass.
* fix(interactive): only render typed command values in fallback text, keep legacy value private
* fix(feishu): gate document-comment command guidance on actual command action
* docs(message-presentation): document command/callback value fallback visibility
* fix(feishu): omit command guidance when URL overrides fallback command text
* docs: regenerate docs_map.md
* fix(interactive): exclude disabled buttons from fallback command rendering and guidance
* fix(interactive): extract hasRenderedCommandAction, exclude disabled buttons from command fallback
* fix(feishu): preserve command guidance marker through core presentation rendering
* fix(feishu): type-narrow channelData.feishu with isRecord before reading rendered-command marker
* fix(feishu): move hasRenderedCommandAction from public SDK into Feishu plugin as local helper
Keep the helper local to the only caller (Feishu outbound) instead of
adding a new public plugin SDK API contract. The shared fallback renderer
in renderMessagePresentationFallbackText already inlines the same
command-visibility logic; a local helper is sufficient for the Feishu
comment-thread guidance gate.
* refactor(feishu): tighten fallback command marker
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Summary:
- The PR adds a `process-exec-boundary` CodeQL high-security shard, wires it into the CodeQL workflow, expands PR path triggers for process-owning plugin/script paths, and updates CI docs.
- PR surface: Docs +1, Config +87. Total +88 across 3 files.
- Reproducibility: not applicable. this is CI/security-scanner configuration rather than a runtime bug. The behavior is source-reviewable and the exact-head `Security High (process-exec-boundary)` check passed.
Automerge notes:
- No ClawSweeper repair was needed after automerge opt-in.
Validation:
- ClawSweeper review passed for head 066d54b633.
- Required merge gates passed before the squash merge.
Prepared head SHA: 066d54b633
Review: https://github.com/openclaw/openclaw/pull/92667#issuecomment-4698545987
Co-authored-by: Mason Huang <masonxhuang@tencent.com>
Approved-by: hxy91819
Cron jobs run in the session they were created from unless the job explicitly requests an isolated fresh session.
Co-authored-by: Peter Steinberger <58493+steipete@users.noreply.github.com>
Summary:
- The branch adds `useAutoCleanupTempDirTracker()`, broadens the temp-dir warning reporter to flag new manual helper imports/usages, updates docs, and migrates two script tests to the new helper.
- PR surface: Tests +301, Docs +1, Other +248. Total +550 across 8 files.
- Reproducibility: not applicable. this is test/tooling cleanup, and the changed behavior is exercised through helper/reporter tests and CI evidence rather than a user reproduction path.
Automerge notes:
- PR branch already contained follow-up commit before automerge: test: harden temp dir helper guard
- PR branch already contained follow-up commit before automerge: test: clarify auto cleanup temp dir helper name
- PR branch already contained follow-up commit before automerge: test: cover existing mkdtemp temp dir forms
- PR branch already contained follow-up commit before automerge: test: read staged temp helper source from index
Validation:
- ClawSweeper review passed for head 1fdd7d2a9a.
- Required merge gates passed before the squash merge.
Prepared head SHA: 1fdd7d2a9a
Review: https://github.com/openclaw/openclaw/pull/93209#issuecomment-4705653665
Co-authored-by: Mason Huang <masonxhuang@tencent.com>
Approved-by: hxy91819
* feat(cli): openclaw attach — launch Claude Code bound to a gateway session with scoped MCP tools
* fix(cli): use token-only MCP config for attach
---------
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
* Diagnose Windows LAN Gateway firewall blocks
* Fix Windows firewall diagnostic lint
* fix: gate gateway firewall diagnostics to local targets
* fix: keep firewall inspection off critical flows
* fix(cli): retry logs.tail after journal fallback in logs follow
Rebase #88159 onto current main and keep systemd journal fallback temporary in follow mode. Preserve the journal cursor across repeated fallback outages, but retry logs.tail on the next loop so recovered Gateway RPC returns to normal log output.
This refresh also replaces the stale red checks-node-core-fast result from the old head with a current-head CI run.
* Keep log source metadata explicit
* ci: retrigger checks for PR #88159
* docs: clarify logs follow JSON source transitions
* fix(cli): keep journal logs responsive during recovery
---------
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
* feat(imessage): add native poll action
Wire the imsg CLI 'poll send' bridge command into the iMessage channel
message-tool action surface, mirroring the existing Discord poll action.
Adds the 'poll' action (gate: polls), a sendPoll runtime, selector-gated
capability advertisement (pollPayloadMessage), config type + zod schema,
regenerated channel metadata, docs, and tests.
* feat(imessage): read inbound polls, vote, and suppress vote echo
Builds on the native poll send action:
- Inbound polls now render to the agent as a readable line (question +
numbered options + tallies) instead of the raw 0xFFFD balloon placeholder,
so a received poll no longer reads as an empty message.
- New `poll-vote` action casts a vote via `imsg poll vote`, resolving a
1-based option index / text / UUID to the poll's option identifier.
- message_tool_only echo guard: the model tends to narrate its choice in a
text reply right after voting ("Blue."), which is redundant since the vote
shows on the poll. A new `poll_vote_echo` suppression reason (alongside
inbound_metadata_echo / internal_runtime_context_echo) drops a send/reply
that exactly restates the just-cast vote, using the option label imsg
returns. Extra content passes through untouched.
* fix(imessage): gate poll-vote on imsg poll.vote rpc capability
Released imsg carries the pollPayloadMessage selector (poll create) but
predates the poll.vote CLI/RPC. Gating both poll and poll-vote on that
selector alone would advertise a vote action the released CLI rejects.
Gate poll-vote additionally on the advertised poll.vote rpc method so this
plugin can ship ahead of the imsg release.
* fix(imessage): enforce poll.vote capability at execution, not just discovery
Codex review flagged the discovery gate as bypassable: a caller that already
knows action=poll-vote skips describeMessageTool and reaches handleAction
directly. Add the same imessageRpcSupportsMethod(status, 'poll.vote') check in
the poll-vote execution path (after assertPrivateApiEnabled), so a direct
dispatch on released imsg fails closed with a clear message instead of an
opaque CLI rejection. Adds a negative handleAction test.
* fix(imessage): harden native poll support
* fix(message): validate targets before channel discovery
* fix(message): validate targets before channel discovery
---------
Co-authored-by: Omar Shahine <lobster@users.noreply.github.com>
Co-authored-by: Omar Shahine <10343873+omarshahine@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
The config example in docs/gateway/config-channels.md incorrectly
listed streaming default as "off". The actual runtime default is
"partial", as confirmed by the Telegram plugin's default resolver.
docs/channels/telegram.md already correctly documents the default
as "partial".
Co-authored-by: Claude <noreply@anthropic.com>
The built-in alias shorthands table listed stale model ids that no longer
match src/config/defaults.ts (DEFAULT_MODEL_ALIASES):
opus: anthropic/claude-opus-4-6 -> anthropic/claude-opus-4-8
gpt: openai/gpt-5.5 -> openai/gpt-5.4
These now match defaults.ts and the help/faq-models alias table, and resolve
an internal contradiction on this same page (its runtime-policy example already
uses anthropic/claude-opus-4-8).
* Route LAN pairing URLs by default route
* Advertise route-aware LAN Control UI links
* Fix route-aware LAN test mocks
* Narrow advertised LAN SDK export
Preserve structured tool-result replay text across provider transports while keeping provider-facing redaction and Anthropic media ordering intact.
Thanks @snowzlmbot!
* feat(openai): add GPT-5.6 series support
* docs: refresh map for GPT-5.6
* fix(openai): preserve GPT-5.6 thinking metadata
* fix(codex): sync managed app server version
* fix(codex): sync managed app server version
* fix(openai): account for GPT-5.6 cache writes
---------
Co-authored-by: Peter Steinberger <steipete@golden-gate.local>
* fix(cron): clear agentTurn thinking override when patched with null
Cron agentTurn patches could clear model/fallbacks/toolsAllow overrides by
sending an explicit null, but thinking had no clear path: the patch schema and
normalizer dropped thinking:null before it reached the merge logic, and the
payload merge only handled string values. Blanking the Thinking/Effort field in
the Cron Control UI therefore silently preserved the old value.
Add thinking:null support across the patch schema, exported type, normalizer,
and payload merge (mirroring model). The Control UI now sends an explicit clear
for model/thinking when an edited job blanks a previously stored override, and
the CLI gains --clear-thinking for parity with --clear-model.
* docs(cron): document --clear-thinking beside sibling clear flags
* fix(plugins): apply output text transforms to toolcall_delta and toolcall_end events
toolcall_delta and toolcall_end events bypassed the output replacement
pipeline, leaking masked tokens (e.g. PII placeholders) into tool call
arguments and external systems.
Closes#97761
* fix(plugins): transform nested tool call arguments in output replacements
Add recursive transformToolCallArgumentText to handle strings, arrays,
and nested objects in tool call arguments, not just the name field.
* fix(plugins): keep tool names unchanged and cover result path
- Remove toolCall.name transformation to prevent breaking tool routing
- Add arguments transform to stream.result()/done.message via
transformContentText for tool-call content blocks
* fix(plugins): narrow argument transform to toolCall content blocks only
Only transform arguments on content blocks with type=toolCall to avoid
touching non-tool-call blocks that happen to have an arguments field.
* test(plugins): assert stream.result() tool-call content block is transformed
* test(plugins): fix result-path fixture to actually contain toolCall block
The previous fixture used makeAssistantMessage('final') which produces
a plain text content block, not a toolCall block. The stream.result()
assertion was vacuously passing.
* style(plugins): fix type cast in result-path test assertion
* fix(agents): preserve tool argument transforms after repair
* refactor(agents): keep tool transform boundary narrow
---------
Co-authored-by: Peter Steinberger <steipete@golden-gate.local>