Commit Graph

11560 Commits

Author SHA1 Message Date
Vincent Koc
7c889e7113 Refactor: trim duplicate gateway/onboarding helpers and dead utils (#43871)
* Gateway: share input provenance schema

* Onboarding: dedupe top-level channel patching

* Utils: remove unused path helpers

* Protocol: refresh generated gateway models
2026-03-12 05:04:31 -04:00
Vincent Koc
cb7b38105f Merge remote-tracking branch 'origin/vincentkoc-code/fix-terminal-table-width'
* origin/vincentkoc-code/fix-terminal-table-width:
  Terminal: consume unsupported escape bytes in tables
  Skills: normalize emoji presentation across outputs
  Changelog: note terminal skills table fixes
  Skills: use Terminal-safe emoji in list output
  Terminal: stop shrinking CLI tables by one column
  Terminal: refine table wrapping and width handling
  Update CHANGELOG.md
  Deps: patch file-type and hono
  Tests: cover emoji table alignment
  Terminal: wrap table cells by grapheme width
  Terminal: measure grapheme display width
  Tests: cover grapheme terminal width
  Changelog: add unreleased March 9 entries

# Conflicts:
#	CHANGELOG.md
#	package.json
#	pnpm-lock.yaml
#	src/cli/skills-cli.format.ts
#	src/terminal/table.test.ts
2026-03-12 04:56:21 -04:00
Xaden Ryan
658bd54ecf feat(llm-task): add thinking override
Co-authored-by: Xaden Ryan <165437834+xadenryan@users.noreply.github.com>
2026-03-12 19:21:35 +11:00
Vincent Koc
f37815b323 Gateway: block profile mutations via browser.request (#43800)
* Gateway: block profile mutations via browser.request

* Changelog: note GHSA-vmhq browser request fix

* Gateway: normalize browser.request profile guard paths
2026-03-12 04:21:03 -04:00
Vincent Koc
46a332385d Gateway: keep spawned workspace overrides internal (#43801)
* Gateway: keep spawned workspace overrides internal

* Changelog: note GHSA-2rqg agent boundary fix

* Gateway: persist spawned workspace inheritance in sessions

* Agents: clean failed lineage spawn state

* Tests: cover lineage attachment cleanup

* Tests: cover lineage thread cleanup
2026-03-12 04:20:00 -04:00
Vincent Koc
97683071b5 Tests: extend exec allowlist glob coverage 2026-03-12 04:01:49 -04:00
Vincent Koc
9aeaa19e9e Agents: clear invalidated Kimi tool arg repair (#43824) 2026-03-12 03:53:06 -04:00
Val Alexander
c5ea6134d0 feat(ui): add chat infrastructure modules (slice 1/3 of dashboard-v2) (#41497)
* feat(ui): add chat infrastructure modules (slice 1 of dashboard-v2)

New self-contained chat modules extracted from dashboard-v2-structure:

- chat/slash-commands.ts: slash command definitions and completions
- chat/slash-command-executor.ts: execute slash commands via gateway RPC
- chat/slash-command-executor.node.test.ts: test coverage
- chat/speech.ts: speech-to-text (STT) support
- chat/input-history.ts: per-session input history navigation
- chat/pinned-messages.ts: pinned message management
- chat/deleted-messages.ts: deleted message tracking
- chat/export.ts: shared exportChatMarkdown helper
- chat-export.ts: re-export shim for backwards compat

Gateway fix:
- Restore usage/cost stripping in chat.history sanitization
- Add test coverage for sanitization behavior

These modules are additive and tree-shaken — no existing code
imports them yet. They will be wired in subsequent slices.

* Update ui/src/ui/chat/export.ts

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* fix(ui): address review feedback on chat infra slice

- export.ts: handle array content blocks (Claude API format) instead
  of silently exporting empty strings
- slash-command-executor.ts: restrict /kill all to current session's
  subagent subtree instead of all sessions globally
- slash-command-executor.ts: only count truly aborted runs (check
  aborted !== false) in /kill summary

* fix: scope /kill <id> to current session subtree and preserve usage.cost in chat.history

- Restrict /kill <id> matching to only subagents belonging to the current
  session's agent subtree (P1 review feedback)
- Preserve nested usage.cost in chat.history sanitization so cost badges
  remain available (P2 review feedback)

* fix(ui): tighten slash kill scoping

* fix(ui): support legacy slash kill scopes

* fix(ci): repair pr branch checks

* Gateway: harden chat abort and export

* UI: align slash commands with session tree scope

* UI: resolve session aliases for slash command lookups

* Update .gitignore

* Cron: use shared nested lane resolver

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-03-12 03:48:58 -04:00
Ayaan Zaidi
ed0ec57a7b fix: scope telegram polling restart to telegram errors (#43799)
* fix: scope telegram polling restart to telegram errors

* fix: make telegram error tagging best-effort

* fix: scope telegram polling restart to telegram errors (#43799)
2026-03-12 13:14:17 +05:30
Vincent Koc
82e3ac21ee Infra: tighten exec allowlist glob matching (#43798)
* Infra: tighten exec allowlist glob matching

* Changelog: note GHSA-f8r2 exec allowlist fix
2026-03-12 03:33:50 -04:00
Vincent Koc
d8ee97c466 Agents: recover malformed Anthropic-compatible tool call args (#42835)
* Agents: recover malformed anthropic tool call args

* Agents: add malformed tool call regression test

* Changelog: note Kimi tool call arg recovery

* Agents: repair toolcall end message snapshots

* Agents: narrow Kimi tool call arg repair
2026-03-12 03:28:22 -04:00
Josh Avant
0bcb95e8fa Models: enforce source-managed SecretRef markers in models.json (#43759)
Merged via squash.

Prepared head SHA: 4a065ef5d8
Co-authored-by: joshavant <830519+joshavant@users.noreply.github.com>
Co-authored-by: joshavant <830519+joshavant@users.noreply.github.com>
Reviewed-by: @joshavant
2026-03-12 02:22:52 -05:00
Mathias Nagler
e8a162d3d8 fix(mattermost): prevent duplicate messages when block streaming + threading are active (#41362)
* fix(mattermost): prevent duplicate messages when block streaming + threading are active

Remove replyToId from createBlockReplyPayloadKey so identical content is
deduplicated regardless of threading target. Add explicit threading dock
to the Mattermost plugin with resolveReplyToMode reading from config
(default "all"), and add replyToMode to the Mattermost config schema.

Fixes #41219

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(mattermost): address PR review — per-account replyToMode and test clarity

Read replyToMode from the merged per-account config via
resolveMattermostAccount so account-level overrides are honored in
multi-account setups. Add replyToMode to MattermostAccountConfig type.
Rename misleading test to clarify it exercises shouldDropFinalPayloads
short-circuit, not payload key dedup.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Replies: keep block-pipeline reply targets distinct

* Tests: cover block reply target-aware dedupe

* Update CHANGELOG.md

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-03-12 03:15:17 -04:00
wangchunyue(王春跃)
6c196c913f fix(cron): prevent duplicate proactive delivery on transient retry (#40646)
* fix(cron): prevent duplicate proactive delivery on transient retry

* refactor: scope skipQueue to retryTransient path only

Non-retrying direct delivery (structured content / thread) keeps the
write-ahead queue so recoverPendingDeliveries can replay after a crash.

Addresses review feedback from codex-connector.

* fix: preserve write-ahead queue on initial delivery attempt

The first call through retryTransientDirectCronDelivery now keeps the
write-ahead queue entry so recoverPendingDeliveries can replay after a
crash.  Only subsequent retry attempts set skipQueue to prevent
duplicate sends.

Addresses second codex-connector review on ea5ae5c.

* ci: retrigger checks

* Cron: bypass write-ahead queue for direct isolated delivery

* Tests: assert isolated cron skipQueue invariants

* Changelog: add cron duplicate-delivery fix entry

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-03-12 03:01:19 -04:00
lisitan
f3c00fce15 fix: prevent duplicate assistant messages in TUI (fixes #35278) (#35364)
* fix: prevent duplicate assistant messages in TUI (fixes #35278)

When startAssistant() is called multiple times with the same runId,
it was creating duplicate AssistantMessageComponent instances instead
of reusing the existing one. This caused messages to appear twice in
the terminal UI.

The fix checks if a component already exists for the runId before
creating a new one. If it exists, we update its text instead of
appending a duplicate component.

Test coverage includes verification that:
- Only one component is created when startAssistant is called twice
- The second text replaces the first
- Component count remains 1 (prevents regression)

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>

* Changelog: add TUI duplicate-render fix entry

---------

Co-authored-by: 沐沐 <mumu@example.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Happy <yesreply@happy.engineering>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-03-12 02:59:42 -04:00
Vincent Koc
99ec687d7a fix(agents): enforce sandboxed session_status visibility (#43754)
* agents: guard sandboxed session_status access

* test(agents): cover sandboxed session_status scope

* docs(changelog): credit session_status hardening

* agents: preflight sandboxed session_status checks

* test(agents): cover session_status existence oracle

* agents: preserve legacy session_status tree keys

* test(agents): cover legacy session_status tree keys

* Update CHANGELOG.md
2026-03-12 02:54:25 -04:00
Vincent Koc
12dc299cde fix(imessage): dedupe reflected self-chat duplicates (#38440)
* iMessage: drop reflected self-chat duplicates

* Changelog: add iMessage self-chat echo dedupe entry

* iMessage: keep self-chat dedupe scoped to final group identity

* iMessage: harden self-chat cache

* iMessage: sanitize self-chat duplicate logs

* iMessage: scope group self-chat dedupe by sender

* iMessage: move self-chat cache identity into cache

* iMessage: hash full self-chat text

* Update CHANGELOG.md
2026-03-12 02:27:35 -04:00
Vincent Koc
d8d8dc7421 Infra: fail closed without device scope baseline 2026-03-12 01:42:12 -04:00
Vincent Koc
276ee259ca Tests: clean up temp git helper directory 2026-03-12 01:42:12 -04:00
Vincent Koc
4f462facda Infra: cap device tokens to approved scopes (#43686)
* Infra: cap device tokens to approved scopes

* Changelog: note device token hardening
2026-03-12 01:25:52 -04:00
Vincent Koc
2504cb6a1e Security: escape invisible exec approval format chars (#43687)
* Infra: escape invisible exec approval chars

* Gateway: sanitize exec approval display text

* Tests: cover sanitized exec approval payloads

* Tests: cover sanitized exec approval forwarding

* Changelog: note exec approval prompt hardening
2026-03-12 01:20:04 -04:00
Vincent Koc
1dcef7b644 Infra: block GIT_EXEC_PATH in host env sanitizer (#43685)
* Infra: block GIT_EXEC_PATH in host env sanitizer

* Changelog: note host env hardening
2026-03-12 01:16:03 -04:00
Vincent Koc
18f15850e6 fix(browser): restore proxy attachment media size cap (#43684)
* browser: honor shared proxy file size cap

* test(browser): cover proxy file size cap

* docs(changelog): note browser proxy size cap fix
2026-03-12 01:04:31 -04:00
Ayaan Zaidi
fbc1bd6f8e fix: clear telegram polling cleanup timers 2026-03-12 09:36:04 +05:30
Huang X
70abee69e9 fix(telegram): avoid polling restart hang after stall detection 2026-03-12 09:36:04 +05:30
Toven
ade748176f OpenRouter: surface free Hunter and Healer stealth models for the next week (#43642)
* Models: add temporary Hunter and Healer alpha to OpenRouter catalog

* Add temporary OpenRouter stealth catalog entries

---------

Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
2026-03-11 22:58:48 -05:00
David Rudduck
f01c41b27a fix(context-engine): guard compact() throw + fire hooks for ownsCompaction engines (#41361)
Merged via squash.

Prepared head SHA: 0957b32dc6
Co-authored-by: davidrudduck <47308254+davidrudduck@users.noreply.github.com>
Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>
Reviewed-by: @jalehman
2026-03-11 20:19:20 -07:00
Frank Yang
5231277163 fix(acp): rehydrate restarted main ACP sessions (#43285)
Merged via squash.

Prepared head SHA: f06318e58f
Co-authored-by: frankekn <4488090+frankekn@users.noreply.github.com>
Co-authored-by: frankekn <4488090+frankekn@users.noreply.github.com>
Reviewed-by: @frankekn
2026-03-12 11:05:09 +08:00
Peter Steinberger
5ca780fa78 feat: expose runtime version in gateway status 2026-03-12 02:55:31 +00:00
Robin Waslander
e95f2dcd6e fix(sandbox): anchor fs-bridge writeFile commit to canonical parent path
Refs: GHSA-xvx8-77m6-gwg6
2026-03-12 03:52:24 +01:00
Peter Steinberger
43a10677ed fix: isolate plugin discovery env from global state 2026-03-12 02:46:29 +00:00
Peter Steinberger
17fd46ab66 test: fix websocket tool shape coverage 2026-03-12 02:16:56 +00:00
Robin Waslander
487a3ba8ce fix(discord): enforce users/roles allowlist in reaction ingress
References GHSA-9vvh-2768-c8vp.
2026-03-12 03:13:46 +01:00
Peter Steinberger
980619b9be fix: harden openai websocket replay 2026-03-12 02:13:06 +00:00
Peter Steinberger
607c158a75 test(cli): update daemon coverage restart contract 2026-03-12 01:43:27 +00:00
Peter Steinberger
b31836317a fix(cli): handle scheduled gateway restarts consistently 2026-03-12 01:38:39 +00:00
Robin Waslander
841ee24340 fix(daemon): address clanker review findings for kickstart restart
Bug 1 (high): replace fixed sleep 1 with caller-PID polling in both
kickstart and start-after-exit handoff modes. The helper now waits until
kill -0 $caller_pid fails before issuing launchctl kickstart -k.

Bug 2 (medium): gate enable+bootstrap fallback on isLaunchctlNotLoaded().
Only attempt re-registration when kickstart -k fails because the job is
absent; all other kickstart failures now re-throw the original error.

Follows up on 3c0fd3dffe.
Fixes #43311, #43406, #43035, #43049
2026-03-12 02:16:24 +01:00
Robin Waslander
b7a37c2023 fix(node-host): extend script-runner set and add fail-closed guard for mutable-file approval
tsx, jiti, ts-node, ts-node-esm, vite-node, and esno were not recognized
as interpreter-style script runners in invoke-system-run-plan.ts. These
runners produced mutableFileOperand: null, causing invoke-system-run.ts
to skip revalidation entirely. A mutated script payload would execute
without the approval binding check that node ./run.js already enforced.

Two-part fix:
- Add tsx, jiti, and related TypeScript/ESM loaders to the known script
  runner set so they produce a valid mutableFileOperand from the planner
- Add a fail-closed runtime guard in invoke-system-run.ts that denies
  execution when a script run should have a mutable-file binding but the
  approval plan is missing it, preventing unknown future runners from
  silently bypassing revalidation

Fixes GHSA-qc36-x95h-7j53
2026-03-12 01:34:35 +01:00
Luke
a5ceb62d44 fix(whatsapp): trim leading whitespace in direct outbound sends (#43539)
Trim leading whitespace from direct WhatsApp text and media caption sends.

Also guard empty text-only web sends after trimming.
2026-03-12 11:32:04 +11:00
Peter Steinberger
7e3787517f fix: harden state dir permissions during onboard 2026-03-12 00:26:36 +00:00
Robin Waslander
ebed3bbde1 fix(gateway): enforce browser origin check regardless of proxy headers
In trusted-proxy mode, enforceOriginCheckForAnyClient was set to false
whenever proxy headers were present. This allowed browser-originated
WebSocket connections from untrusted origins to bypass origin validation
entirely, as the check only ran for control-ui and webchat client types.

An attacker serving a page from an untrusted origin could connect through
a trusted reverse proxy, inherit proxy-injected identity, and obtain
operator.admin access via the sharedAuthOk / roleCanSkipDeviceIdentity
path without any origin restriction.

Remove the hasProxyHeaders exemption so origin validation runs for all
browser-originated connections regardless of how the request arrived.

Fixes GHSA-5wcw-8jjv-m286
2026-03-12 01:16:52 +01:00
Robin Waslander
3c0fd3dffe fix(daemon): replace bootout with kickstart -k for launchd restarts on macOS
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
2026-03-12 01:16:49 +01:00
Peter Steinberger
e11be576fb fix: repair bundled plugin dirs after npm install 2026-03-11 23:53:50 +00:00
Vincent Koc
b6d83749c8 fix(terminal): sanitize skills JSON and fallback on legacy Windows (#43520)
* Terminal: use ASCII borders on legacy Windows consoles

* Skills: sanitize JSON output for control bytes

* Changelog: credit terminal follow-up fixes

* Update CHANGELOG.md

* Update CHANGELOG.md

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* Skills: strip remaining escape sequences from JSON output

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
2026-03-11 19:53:07 -04:00
Peter Steinberger
0e397e62b7 chore: bump version to 2026.3.10 2026-03-11 23:29:53 +00:00
Brian Yu
cced1e0f76 preserve openai phase param 2026-03-11 23:15:52 +00:00
Gustavo Madeira Santana
da6f97a3f6 Memory: revalidate multimodal files before indexing 2026-03-11 22:51:34 +00:00
zhoulf1006
453c8d7c1b fix(hooks): add missing trigger and channelId to agent_end, llm_input, and llm_output hook contexts (#42362)
Merged via squash.

Prepared head SHA: e6d7b7e31a
Co-authored-by: zhoulf1006 <35586967+zhoulf1006@users.noreply.github.com>
Co-authored-by: hydro13 <6640526+hydro13@users.noreply.github.com>
Reviewed-by: @hydro13
2026-03-11 23:40:13 +01:00
Gustavo Madeira Santana
d79ca52960 Memory: add multimodal image and audio indexing (#43460)
Merged via squash.

Prepared head SHA: a994c07190
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
2026-03-11 22:28:34 +00:00
Harold Hunt
20d097ac2f Gateway/Dashboard: surface config validation issues (#42664)
Merged via squash.

Prepared head SHA: 43f66cdcf0
Co-authored-by: huntharo <5617868+huntharo@users.noreply.github.com>
Co-authored-by: huntharo <5617868+huntharo@users.noreply.github.com>
Reviewed-by: @huntharo
2026-03-11 17:32:41 -04:00