Telegram: use Grammy types directly, add typed Probe/Audit to plugin interface#8403
Telegram: use Grammy types directly, add typed Probe/Audit to plugin interface#8403christianklotz merged 5 commits intomainfrom
Conversation
|
Addressed Greptile feedback on |
|
Note: #8392 and #8368 will conflict with this PR — they both modify
Both PRs should rebase on top of this one if it lands first. |
obviyus
left a comment
There was a problem hiding this comment.
Great PR! Moving to canonical @grammyjs/types should help a lot in avoidng local type sprawl and drift
| date: origin.date, | ||
| type: "channel", | ||
| signature: origin.author_signature, | ||
| }); |
There was a problem hiding this comment.
Minor nit: should we have a default case here? Or is origin.type only ever going to be the above four values?
There was a problem hiding this comment.
Added an exhaustiveness guard with origin satisfies never in the default case. TypeScript will flag a compile error if Grammy adds a new MessageOrigin variant, and at runtime unknown types gracefully return null.
…it generics to plugin interface
… simplify required-field checks
73b8a23 to
8bc29e8
Compare
|
Hey @christianklotz — thanks for the heads-up on the conflict! The rebase for #8392 is done and builds cleanly on top of your Grammy types refactor:
All 394 Telegram tests passing. If you think #8392 complements your work nicely and want to drop a 👍 over there, I'd appreciate it! |
…interface (openclaw#8403) * Telegram: replace duplicated types with Grammy imports, add Probe/Audit generics to plugin interface * Telegram: remove legacy forward metadata (deprecated in Bot API 7.0), simplify required-field checks * Telegram: clean up remaining legacy references and unnecessary casts * Telegram: keep RequestInit parameter type in proxy fetch (addresses review feedback) * Telegram: add exhaustiveness guard to resolveForwardOrigin switch
…interface (openclaw#8403) * Telegram: replace duplicated types with Grammy imports, add Probe/Audit generics to plugin interface * Telegram: remove legacy forward metadata (deprecated in Bot API 7.0), simplify required-field checks * Telegram: clean up remaining legacy references and unnecessary casts * Telegram: keep RequestInit parameter type in proxy fetch (addresses review feedback) * Telegram: add exhaustiveness guard to resolveForwardOrigin switch
…interface (openclaw#8403) * Telegram: replace duplicated types with Grammy imports, add Probe/Audit generics to plugin interface * Telegram: remove legacy forward metadata (deprecated in Bot API 7.0), simplify required-field checks * Telegram: clean up remaining legacy references and unnecessary casts * Telegram: keep RequestInit parameter type in proxy fetch (addresses review feedback) * Telegram: add exhaustiveness guard to resolveForwardOrigin switch
* docs: note docker allow-unconfigured behavior
* fix: start gateway in docker CMD (#6635) (thanks @kaizen403)
* test: cover SSRF blocking for attachment URLs
* fix: polish docker setup flow
* chore: We have a sleep at home. The sleep at home:
* fix(update): harden global updates
* chore: fix broken test.
* fix: expand SSRF guard coverage
* fix: stabilize docker e2e flows
* fix(telegram): handle Grammy HttpError network failures (#3815) (#7195)
* fix(telegram): handle Grammy HttpError network failures (#3815)
Grammy wraps fetch errors in an .error property (not .cause). Added .error
traversal to collectErrorCandidates in network-errors.ts.
Registered scoped unhandled rejection handler in monitorTelegramProvider
to catch network errors that escape the polling loop (e.g., from setMyCommands
during bot setup). Handler is unregistered when the provider stops.
* fix(telegram): address review feedback for Grammy HttpError handling
- Gate .error traversal on HttpError name to avoid widening search graph
- Use runtime logger instead of console.warn for consistency
- Add isGrammyHttpError check to scope unhandled rejection handler
- Consolidate isNetworkRelatedError into isRecoverableTelegramNetworkError
- Add 'timeout' to recoverable message snippets for full coverage
* CI: label maintainer issues
* Docs i18n: harden doc-mode pipeline
* Docs: add zh-CN translations
* Docs: fix zh-CN template time wording
What: replace <2/<30 text in zh-CN AGENTS template with safe wording
Why: avoid MDX parse errors during docs build
Tests: not run (doc text change)
* docs: add changelog for zh-CN translations (#6619) (thanks @joshp123)
* Docs: fix zh-CN ClawHub link
What: wrap clawhub.com in an explicit URL link in zh-CN skills doc
Why: avoid Mintlify broken-link parser treating trailing punctuation as part of the URL
Tests: not run (doc text change)
* Docs: use explicit ClawHub markdown link
What: switch clawhub.com reference to explicit Markdown link syntax
Why: MDX parser rejects angle-bracket autolinks
Tests: not run (doc text change)
* Docs i18n: tune zh-CN prompt + glossary
What: enforce zh-CN tone (你/你的), Skills/local loopback/Tailscale terms, Gateway网关
Why: keep future translation output consistent with issue feedback
Tests: not run (prompt/glossary change)
* Docs: normalize zh-CN terminology + tone
What: switch to 你/你的 tone; standardize Skills/Gateway网关/local loopback/私信 wording
Why: align zh-CN docs with issue 6995 feedback + idiomatic tech style
Tests: pnpm docs:build
* Tests: stub SSRF DNS pinning (#6619) (thanks @joshp123)
* fix(webchat): respect user scroll position during streaming and refresh
- Increase near-bottom threshold from 200px to 450px so one long message
doesn't falsely register as 'near bottom'
- Make force=true only override on initial load (chatHasAutoScrolled=false),
not on subsequent refreshChat() calls
- refreshChat() no longer passes force=true to scheduleChatScroll
- Add chatNewMessagesBelow flag for future 'scroll to bottom' button UI
- Clear chatNewMessagesBelow when user scrolls back to bottom
- Add 13 unit tests covering threshold, force behavior, streaming, and reset
* fix: address review feedback — retryDelay uses effectiveForce, default overrides param, @state() on chatNewMessagesBelow
* Docs: expand zh-Hans nav and fix assets
* Docs: expand zh-Hans nav (#7242) (thanks @joshp123)
* fix(ui): add core state and logic for scroll control
* feat(ui): add new messages indicator button
* docs: update changelog for PR #7226
* chore: fix formatting and CI
* iOS: wire node services and tests
* iOS: stabilize talk mode tests
* Gateway: fix node invoke receive loop
* Gateway: wait for snapshot before connect
* Agents: add nodes invoke action
* iOS: fix node notify and identity
* iOS: streamline notify timeouts
* iOS: add write commands for contacts/calendar/reminders
* iOS: add push-to-talk node commands
* iOS: pause voice wake during PTT
* iOS: add PTT once/cancel
* Gateway: add PTT chat + nodes CLI
* iOS: wire node commands and incremental TTS
* iOS: update onboarding and gateway UI
* Core: update shared gateway models
* iOS: improve gateway auto-connect and voice permissions
* Docs: add zh-CN landing notice + AI image
* Docs: add zh-CN landing note (#7303) (thanks @joshp123)
* Docs: expand zh-CN landing note
* Revert "iOS: wire node services and tests"
This reverts commit 7b0a0f3dace575c33dafb61d4a13cdef4dd0d64e.
* Revert "Core: update shared gateway models"
This reverts commit 37eaca719a68aa1ad9dcbfe83c8a20e88bb6951a.
* fix: resolve check errors in nodes-tool and commands-ptt
* feat(config): default thinking for sessions_spawn subagents (#7372)
* feat(config): add subagent default thinking
* fix: accept config subagents.thinking + stabilize test mocks (#7372) (thanks @tyler6204)
* fix: use findLast instead of clearAllMocks in test (#7372)
* fix: correct test assertions for tool result structure (#7372)
* fix: remove unnecessary type assertion after rebase
* fix: validate AbortSignal instances before calling AbortSignal.any()
Fixes #7269
* refactor: use structural typing instead of instanceof for AbortSignal check
Address P1 review feedback from Greptile: instanceof AbortSignal may be
unreliable across different realms (VM, iframe, etc.) where the AbortSignal
constructor may differ. Use structural typing (checking for aborted property
and addEventListener method) for more robust cross-realm compatibility.
* fix: validate AbortSignal instances before calling AbortSignal.any() (#7277) (thanks @Elarwei001)
* fix(tools): ensure file_path alias passes validation in read/write tools (#7451)
Co-authored-by: lotusfall <lotusfall@outlook.com>
* fix: skip audio files from text extraction to prevent binary processing (#7475)
* fix: skip audio files from text extraction early
Audio files should not be processed through extractFileBlocks for text
extraction - they are handled by the dedicated audio transcription
capability (STT).
Previously, audio files were only skipped if they didn't "look like text"
(looksLikeUtf8Text check). This caused issues where some audio binary
data (e.g., long Telegram voice messages) could accidentally pass the
heuristic check and get processed as text content.
This fix:
1. Adds audio to the early skip alongside image/video (more efficient)
2. Removes the redundant secondary check that had the flawed condition
Fixes audio binary being incorrectly processed as text in Telegram and
other platforms.
* Media: skip binary media in file extraction (#7475) (thanks @AlexZhangji)
---------
Co-authored-by: Shakker <shakkerdroid@gmail.com>
* fix(telegram): recover from grammY "timed out" long-poll errors (#7239)
grammY getUpdates returns "Request to getUpdates timed out after 500 seconds"
but RECOVERABLE_MESSAGE_SNIPPETS only had "timeout". Since
"timed out".includes("timeout") === false, the error was not classified as
recoverable, causing the polling loop to exit permanently.
Add "timed out" to RECOVERABLE_MESSAGE_SNIPPETS so the polling loop retries
instead of dying silently.
Fixes #7239
Fixes #7255
* fix(telegram): recover from grammY long-poll timeouts (#7466) (thanks @macmimi23)
* Docs: fix compatibility shim note
* Agent: repair malformed tool calls and session files
* Changelog: note tool call repair
* Agents: fix lint in tool-call sanitizers
* Agents: harden session file repair
* Agents: flush pending tool results on drop
* Docs: simplify transcript hygiene scope
* fix: repair malformed tool calls and session transcripts (#7473) (thanks @justinhuangcode)
* chore: Update deps.
* fix(slack): fail closed on slash command channel type lookup
* fix: harden exec allowlist parsing
* fix(gateway): require shared auth before device bypass
* style(ui): format resizable divider
* chore: Fix CI.
* Docs: clarify whats new FAQ heading (#7394)
* feat(ui): add Agents dashboard
* Security: new openclaw-system-admin skill + bootstrap audit
* Security: rename openclaw-system-admin skill to healthcheck
* Security: remove openclaw-system-admin skill path
* Security: refine healthcheck workflow
* Security: healthcheck skill (#7641) (thanks @Takhoffman)
* chore: fix CI
* chore: fix formatting
* Security: tune bootstrap healthcheck prompt + healthcheck wording
* chore: fix formatting
* CLI: restore terminal state on exit
* Onboarding: keep TUI flow exclusive
* fix: error handling in restore failure reporting
* feat (memory): Implement new (opt-in) QMD memory backend
* Make memory more resilient to failure
* Add more tests; make fall back more resilient and visible
* Fix build errors
* fix(qmd): use XDG dirs for qmd home; drop ollama docs
* fix(memory-qmd): write XDG index.yml + legacy compat
* fix(memory-qmd): create collections via qmd CLI (no YAML)
* Add how to trigger model downloads for qmd in documentation
* fix(memory/qmd): throttle embed + citations auto + restore --force
* Tests: use OPENCLAW_STATE_DIR in qmd manager
* Docs: align QMD state dir with OpenClaw
* Memory: parse quoted qmd command
* Memory: fix QMD scope channel parsing
* Memory: harden QMD memory_get path checks
* Memory: clamp QMD citations to injected budget
* Tests: cover QMD scope, reads, and citation clamp
* QMD: use OpenClaw config types
* Fix build regressions after merge
* Lint: add braces for single-line ifs
* fix: make QMD cache key deterministic
* fix: derive citations chat type via session parser
* chore: apply formatter
* chore: restore OpenClaw branding
* chore: fix lint warnings
* chore: oxfmt
* fix: restore session_status and CLI examples
* chore: oxfmt
* fix: restore safety + session_status hints
* chore: oxfmt
* fix: changelog entry for QMD memory (#3160) (thanks @vignesh07)
* docs: finish renaming memory state dir references
* CLI: cache shell completion scripts
* Install: cache completion scripts on install/update
* Onboarding: drop completion prompt
* chore: update changelog for completion caching
* chore: Migrate to tsdown, speed up JS bundling by ~10x (thanks @hyf0).
The previous migration to tsdown was reverted because it caused a ~20x slowdown when running OpenClaw from the repo. @hyf0 investigated and found that simply renaming the `dist` folder also caused the same slowdown. It turns out the Plugin script loader has a bunch of voodoo vibe logic to determine if it should load files from source and compile them, or if it should load them from dist. When building with tsdown, the filesystem layout is different (bundled), and so some files weren't in the right location, and the Plugin script loader decided to compile source files from scratch using Jiti.
The new implementation uses tsdown to embed `NODE_ENV: 'production'`, which we now use to determine if we are running OpenClaw from a "production environmen" (ie. from dist). This removes the slop in favor of a deterministic toggle, and doesn't rely on directory names or similar.
There is some code reaching into `dist` to load specific modules, primarily in the voice-call extension, which I simplified into loading an "officially" exported `extensionAPI.js` file. With tsdown, entry points need to be explicitly configured, so we should be able to avoid sloppy code reaching into internals from now on. This might break some existing users, but if it does, it's because they were using "private" APIs.
* fix: CI: We no longer need to test the tsc build with Bun, we are always using `tsdown` to build now.
* fix: Remove `tsconfig.oxlint.json` AGAIN.
* feat: remove slop.
* chore: clean up git hooks and actually install them again.
* fix: Fix Mac app build step.
* chore: Fix all TypeScript errors in `ui`.
* chore: Switch to `NodeNext` for `module`/`moduleResolution` in `ui`.
* chore: Merge tsconfigs, typecheck `ui` as part of `pnpm tsgo` locally and on CI.
* Skills: refine healthcheck guidance
* fix(voice-call): harden inbound policy
* fix(matrix): harden allowlists
* fix: harden Windows exec allowlist
* docs: Update information architecture for OpenClaw docs (#7622)
* docs: restructure navigation into 5 tabs for better IA
* dedupe redirects
* use 8 tabs
* add missing /index extensions
* update zh navigation
* remove `default: true` and rearrange languages
* add missing redirects
* format:fix
* docs: update IA tabs + restore /images redirect (#7622) (thanks @ethanpalm)
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* fix: restore OpenClaw docs/source links in system prompt
* chore: prepare 2026.2.2 release
* fix(ui): fix web UI after tsdown migration and typing changes
* fix(skills): warn when bundled dir missing
* fix(ui): refresh agent files after external edits
* fix(ui): note agent file refresh in changelog
* Docs: refresh zh-CN translations + i18n guidance
What:
- update zh-CN glossary, translation prompt, and TM
- regenerate zh-CN docs and apply targeted fixes
- add zh-CN AGENTS guidance for translation pipeline
Why:
- address zh-CN terminology and spacing feedback from #6995
Tests:
- pnpm build && pnpm check && pnpm test
* Docs: update zh-CN translations and pipeline
What:
- update zh-CN glossary, TM, and translator prompt
- regenerate zh-CN docs and apply targeted fixes
- add zh-CN AGENTS pipeline guidance
Why:
- address terminology/spacing feedback from #6995
Tests:
- pnpm build && pnpm check && pnpm test
* Docs(zh-CN): add AGENTS translation workflow
* Channels: add Feishu/Lark support
* Channels: finish Feishu/Lark integration
* fix: harden control ui framing + ws origin
* fix(approvals): gate /approve by gateway scopes
* test: add /approve gateway scope coverage (#1) (thanks @mitsuhiko)
* test: reset /approve mock per test (#1) (thanks @mitsuhiko)
* chore: prep 2026.2.2 docs/release checks
* chore: update appcast for 2026.2.2
* chore: add mac dSYM zip to release artifacts
* fix: use build-info for version fallback
* Docs: guard zh-CN i18n workflow
What:
- document zh-CN docs pipeline and generated-doc guardrails
- note Discord escalation when the pipeline drags
Why:
- prevent accidental edits to generated translations
Tests:
- pnpm build
- pnpm check
- pnpm test
Co-authored-by: Josh Palmer <joshpalmer123@gmail.com>
* chore: bump version to 2026.2.2-1
* fix: improve build-info resolution for commit/version
* Docs: drop healthcheck from bootstrap
* fix(update): honor update.channel for update.run
* fix: enforce Nextcloud Talk allowlist by user id
* feat: add configurable web_fetch maxChars cap
* fix(matrix): require unique allowlist matches in wizard
* fix: add legacy daemon-cli shim for updates
* iMessage: promote BlueBubbles and refresh docs/skills (#8415)
* feat: Make BlueBubbles the primary iMessage integration
- Remove old imsg skill (skills/imsg/SKILL.md)
- Create new BlueBubbles skill (skills/bluebubbles/SKILL.md) with message tool examples
- Add keep-alive script documentation for VM/headless setups to docs/channels/bluebubbles.md
- AppleScript that pokes Messages.app every 5 minutes
- LaunchAgent configuration for automatic execution
- Prevents Messages.app from going idle in VM environments
- Update all documentation to prioritize BlueBubbles over legacy imsg:
- Mark imsg channel as legacy throughout docs
- Update README.md channel lists
- Update wizard, hubs, pairing, and index docs
- Update FAQ to recommend BlueBubbles for iMessage
- Update RPC docs to note imsg as legacy pattern
- Update Chinese documentation (zh-CN)
- Replace imsg examples with generic macOS skill examples where appropriate
BlueBubbles is now the recommended first-class iMessage integration,
with the legacy imsg integration marked for potential future removal.
* refactor: Update import paths and improve code formatting
- Adjusted import paths in session-status-tool.ts, whatsapp-heartbeat.ts, and heartbeat-runner.ts for consistency.
- Reformatted code for better readability by aligning and grouping related imports and function parameters.
- Enhanced error messages and conditional checks for clarity in heartbeat-runner.ts.
* skills: restore imsg skill and align bluebubbles skill
* docs: update FAQ for clarity and formatting
- Adjusted the formatting of the FAQ section to ensure consistent bullet point alignment.
- No content changes were made, only formatting improvements for better readability.
* style: oxfmt touched files
* fix: preserve BlueBubbles developer reference (#8415) (thanks @tyler6204)
* refactor: remove unnecessary blank line in policy test file
* chore: bump version to 2026.2.3
* feat: add new messages indicator style for chat interface
- Introduced a floating pill element above the compose area to indicate new messages.
- Styled the indicator with hover effects and responsive design for better user interaction.
* Telegram: add inline button model selection for /models and /model commands
* Telegram: fix model button review issues
- Add currentModel to callback handler for checkmark display
- Add 64-byte callback_data limit protection (skip long model IDs)
- Add tests for large model lists and callback_data limits
* fix: honor telegram model overrides in buttons (#8193) (thanks @gildo)
* chore: update changelog for #8193 (thanks @gildo)
* feat(discord): add set-presence action for bot activity and status
Bridge the agent tools layer to the Discord gateway WebSocket via a new
gateway registry, allowing agents to set the bot's activity and online
status. Supports playing, streaming, listening, watching, custom, and
competing activity types. Custom type uses activityState as the sidebar
text; other types show activityName in the sidebar and activityState in
the flyout. Opt-in via channels.discord.actions.presence (default false).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* Address PR feedback
* Make openclaw consistent in this file (#8533)
Co-authored-by: stephenchen2025 <schenjobs@gmail.com>
* style: update chat new-messages button
* feat: add support for Moonshot API key for China endpoint
* fix: keep Moonshot CN base URL in onboarding (#7180) (thanks @waynelwz)
* docs(skills): split tmux send-keys for TUI (#7737)
* docs(skills): split tmux send-keys for TUI
* docs(skills): soften TUI send-keys wording
---------
Co-authored-by: wangnov <1694546283@qq.com>
* docs: note tmux send-keys TUI guidance (#7737) (thanks @Wangnov)
* fix(control-ui): resolve header logo when gateway.controlUi.basePath is set (#7178)
* fix(control-ui): resolve header logo when gateway.controlUi.basePath is set
* refactor(control-ui): header logo under basePath; normalize logo URL with normalizeBasePath
* docs: add changelog for #7178 (thanks @Yeom-JinHo)
* docs: document secure DM mode preset (#7872)
* docs: document secure DM mode preset
* fix: resolve merge conflict in resizable-divider
* fix(security): separate untrusted channel metadata from system prompt (thanks @KonstantinMirin)
* docs: update Feishu plugin docs
* feat: Add Docs Chat Widget with RAG-powered Q&A (#7908)
* feat: add docs chat prototype and related scripts
- Introduced a minimal documentation chatbot that builds a search index from markdown files and serves responses via an API.
- Added scripts for building the index and serving the chat API.
- Updated package.json with new commands for chat index building and serving.
- Created a new Vercel configuration file for deployment.
- Added a README for the docs chat prototype detailing usage and integration.
* feat: enhance docs chat with vector-based RAG pipeline
- Added vector index building and serving capabilities to the docs chat.
- Introduced new scripts for generating embeddings and serving the chat API using vector search.
- Updated package.json with new commands for vector index operations.
- Enhanced README with instructions for the new RAG pipeline and legacy keyword pipeline.
- Removed outdated Vercel configuration file.
* feat: enhance chat widget with markdown rendering and style updates
- Integrated dynamic loading of markdown rendering for chat responses.
- Implemented a fallback for markdown rendering to ensure consistent display.
- Updated CSS variables for improved theming and visual consistency.
- Enhanced chat bubble and input styles for better user experience.
- Added new styles for markdown content in chat bubbles, including code blocks and lists.
* feat: add copy buttons to chat widget for enhanced user interaction
- Implemented copy buttons for chat responses and code blocks in the chat widget.
- Updated CSS styles for improved visibility and interaction of copy buttons.
- Adjusted textarea height for better user experience.
- Enhanced functionality to allow users to easily copy text from chat bubbles and code snippets.
* feat: update chat widget styles for improved user experience
- Changed accent color for better visibility.
- Enhanced preformatted text styles for code blocks, including padding and word wrapping.
- Adjusted positioning and styles of copy buttons for chat responses and code snippets.
- Improved hover effects for copy buttons to enhance interactivity.
* feat: enhance chat widget styles for better responsiveness and scrollbar design
- Updated chat panel dimensions for improved adaptability on various screen sizes.
- Added custom scrollbar styles for better aesthetics and usability.
- Adjusted chat bubble styles for enhanced visibility and interaction.
- Improved layout for expanded chat widget on smaller screens.
* feat: refine chat widget code block styles and copy button functionality
- Adjusted padding and margin for preformatted text in chat responses for better visual consistency.
- Introduced a compact style for single-line code blocks to enhance layout.
- Updated copy button logic to skip short code blocks, improving user experience when copying code snippets.
* feat: add resize handle functionality to chat widget for adjustable panel width
- Implemented a draggable resize handle for the chat widget's sidebar, allowing users to adjust the panel width.
- Added CSS styles for the resize handle, including hover effects and responsive behavior.
- Integrated drag-to-resize logic to maintain user-set width across interactions.
- Ensured the panel resets to default width when closed, enhancing user experience.
* feat: implement rate limiting and error handling in chat API
- Added rate limiting functionality to the chat API, allowing a maximum number of requests per IP within a specified time window.
- Implemented error handling for rate limit exceeded responses, including appropriate headers and retry instructions.
- Enhanced error handling for other API errors, providing user-friendly messages for various failure scenarios.
- Updated README to include new environment variables for rate limiting configuration.
* feat: integrate Upstash Vector for enhanced document retrieval in chat API
- Implemented Upstash Vector as a cloud-based storage solution for document chunks, replacing the local LanceDB option.
- Added auto-detection of storage mode based on environment variables for seamless integration.
- Updated the chat API to utilize the new retrieval mechanism, enhancing response accuracy and performance.
- Enhanced README with setup instructions for Upstash and updated environment variable requirements.
- Introduced new scripts and configurations for managing the vector index and API interactions.
* feat: add create-markdown-preview.js for markdown rendering
- Introduced a new script for framework-agnostic HTML rendering of markdown content.
- The script includes various parsing functions to handle different markdown elements.
- Updated the chat widget to load the vendored version of @create-markdown/preview for improved markdown rendering.
* docs: update README for Upstash Vector index setup and environment variables
- Enhanced instructions for creating a Vector index in Upstash, including detailed settings and important notes.
- Clarified environment variable requirements for both Upstash and LanceDB modes.
- Improved formatting and organization of setup steps for better readability.
- Added health check and API endpoint details for clearer usage guidance.
* feat: add TRUST_PROXY environment variable for IP address handling
- Introduced the TRUST_PROXY variable to control the trust of X-Forwarded-For headers when behind a reverse proxy.
- Updated the README to document the new environment variable and its default value.
- Enhanced the getClientIP function to conditionally trust proxy headers based on the TRUST_PROXY setting.
* feat: add ALLOWED_ORIGINS environment variable for CORS configuration
- Introduced the ALLOWED_ORIGINS variable to specify allowed origins for CORS, enhancing security and flexibility.
- Updated the README to document the new environment variable and its usage.
- Refactored CORS handling in the server code to utilize the ALLOWED_ORIGINS setting for dynamic origin control.
* fix: ensure complete markdown rendering in chat widget
- Added logic to flush any remaining buffered bytes from the decoder, ensuring that all text is rendered correctly in the assistant bubble.
- Updated the assistant bubble's innerHTML to reflect the complete markdown content after streaming completes.
* feat: enhance DocsStore with improved vector handling and similarity conversion
- Added a constant for the distance metric used in vector searches, clarifying the assumption of L2 distance.
- Updated the createTable method to ensure all chunk properties are correctly mapped during table creation.
- Improved the similarity score calculation by providing a clear explanation of the conversion from L2 distance, ensuring accurate ranking of results.
* chore: fix code formatting
* Revert "chore: fix code formatting"
This reverts commit 6721f5b0b7bf60b76c519ccadfa41742f19ecf87.
* chore: format code for improved readability
- Reformatted code in serve.ts to enhance readability by adjusting indentation and line breaks.
- Ensured consistent style for function return types and object properties throughout the file.
* feat: Update API URL selection logic in chat widget
- Enhanced the API URL configuration to prioritize explicit settings, defaulting to localhost for development and using a production URL otherwise.
- Improved clarity in the code by adding comments to explain the logic behind the API URL selection.
* chore: Update documentation structure for improved organization
- Changed the path for the "Start Here" page to "start/index" for better clarity.
- Reformatted the "Web & Interfaces" and "Help" groups to use multi-line arrays for improved readability.
* feat: Enhance markdown preview integration and improve chat widget asset loading
- Wrapped the markdown preview functionality in an IIFE to expose a global API for easier integration.
- Updated the chat widget to load the markdown preview library dynamically, checking for existing instances to avoid duplicate loads.
- Adjusted asset paths in the chat widget to ensure correct loading based on the environment (local or production).
- Added CORS headers in the Vercel configuration for improved API accessibility.
* fix: Update chat API URL to include '/api' for correct endpoint access
- Modified the chat configuration and widget files to append '/api' to the API URL, ensuring proper endpoint usage in production and local environments.
* refactor: Simplify docs-chat configuration and remove unused scripts
- Removed outdated scripts and configurations related to the docs-chat feature, including build and serve scripts, as well as the associated package.json and README files.
- Streamlined the API URL configuration in the chat widget for better clarity and maintainability.
- Updated the package.json to remove unnecessary scripts related to the now-deleted functionality.
* refactor: Update documentation structure for improved clarity
- Changed the path for the "Start Here" page from "start/index" to "index" to enhance navigation and organization within the documentation.
* chore: Remove unused dependencies from package.json and pnpm-lock.yaml
- Deleted `@lancedb/lancedb`, `@upstash/vector`, and `openai` from both package.json and pnpm-lock.yaml to streamline the project and reduce bloat.
* chore: Clean up .gitignore by removing obsolete entries
- Deleted unused entries related to the docs-chat vector database from .gitignore to maintain a cleaner configuration.
* chore: Remove deprecated chat configuration and markdown preview script
- Deleted the `create-markdown-preview.js` script and the `docs-chat-config.js` file to eliminate unused assets and streamline the project.
- Updated the `docs-chat-widget.js` to directly reference the markdown library from a CDN, enhancing maintainability.
* chore: Update markdown rendering in chat widget to use marked library
- Replaced the deprecated `create-markdown-preview` library with the `marked` library for markdown rendering.
- Adjusted the script loading mechanism to fetch `marked` from a CDN, improving performance and maintainability.
- Enhanced the markdown rendering function to ensure security by disabling HTML pass-through and opening links in new tabs.
* Delete docs/start/index.md
* fix: harden voice-call webhook verification
* fix(cron): fix timeout, add timestamp validation, enable file sync
Fixes #7667
Task 1: Fix cron operation timeouts
- Increase default gateway tool timeout from 10s to 30s
- Increase cron-specific tool timeout to 60s
- Increase CLI default timeout from 10s to 30s
- Prevents timeouts when gateway is busy with long-running jobs
Task 2: Add timestamp validation
- New validateScheduleTimestamp() function in validate-timestamp.ts
- Rejects atMs timestamps more than 1 minute in the past
- Rejects atMs timestamps more than 10 years in the future
- Applied to both cron.add and cron.update operations
- Provides helpful error messages with current time and offset
Task 3: Enable file sync for manual edits
- Track file modification time (storeFileMtimeMs) in CronServiceState
- Check file mtime in ensureLoaded() and reload if changed
- Recompute next runs after reload to maintain accuracy
- Update mtime after persist() to prevent reload loop
- Dashboard now picks up manual edits to ~/.openclaw/cron/jobs.json
* feat(cron): introduce delivery modes for isolated jobs
- Added support for new delivery modes in cron jobs: `announce`, `deliver`, and `none`.
- Updated documentation to reflect changes in delivery options and usage examples.
- Enhanced the cron job schema to include delivery configuration.
- Refactored related CLI commands and UI components to accommodate the new delivery settings.
- Improved handling of legacy delivery fields for backward compatibility.
This update allows users to choose how output from isolated jobs is delivered, enhancing flexibility in job management.
* feat(cron): default isolated jobs to announce delivery and enhance scheduling options
- Updated isolated cron jobs to default to `announce` delivery mode, improving user experience.
- Enhanced scheduling options to accept ISO 8601 timestamps for `schedule.at`, while still supporting epoch milliseconds.
- Refined documentation to clarify delivery modes and scheduling formats.
- Adjusted related CLI commands and UI components to reflect these changes, ensuring consistency across the platform.
- Improved handling of legacy delivery fields for backward compatibility.
This update streamlines the configuration of isolated jobs, making it easier for users to manage job outputs and schedules.
* feat(cron): enhance one-shot job behavior and CLI options
- Default one-shot jobs to delete after success, improving job management.
- Introduced `--keep-after-run` CLI option to allow users to retain one-shot jobs post-execution.
- Updated documentation to clarify default behaviors and new options for one-shot jobs.
- Adjusted cron job creation logic to ensure consistent handling of delete options.
- Enhanced tests to validate new behaviors and ensure reliability.
This update streamlines the handling of one-shot jobs, providing users with more control over job persistence and execution outcomes.
* feat(cron): enhance delivery modes and job configuration
- Updated isolated cron jobs to support new delivery modes: `announce` and `none`, improving output management.
- Refactored job configuration to remove legacy fields and streamline delivery settings.
- Enhanced the `CronJobEditor` UI to reflect changes in delivery options, including a new segmented control for delivery mode selection.
- Updated documentation to clarify the new delivery configurations and their implications for job execution.
- Improved tests to validate the new delivery behavior and ensure backward compatibility with legacy settings.
This update provides users with greater flexibility in managing how isolated jobs deliver their outputs, enhancing overall usability and clarity in job configurations.
* feat(cron): set default enabled state for cron jobs
- Added logic to default the `enabled` property to `true` if not explicitly set as a boolean in the cron job input.
- Updated job creation and store functions to ensure consistent handling of the `enabled` state across the application.
- Enhanced input normalization to improve job configuration reliability.
This update ensures that cron jobs are enabled by default, enhancing user experience and reducing potential misconfigurations.
* refactor(cron): update delivery instructions for isolated agent
- Revised the delivery instructions in the isolated agent's command body to clarify that summaries should be returned as plain text and will be delivered by the main agent.
- Removed the previous directive regarding messaging tools to streamline communication guidelines.
This change enhances clarity in the delivery process for isolated agent tasks.
* feat(cron): enhance delivery handling and testing for isolated jobs
- Introduced new properties for explicit message targeting and message tool disabling in the EmbeddedRunAttemptParams type.
- Updated cron job tests to validate best-effort delivery behavior and handling of delivery failures.
- Added logic to clear delivery settings when switching session targets in cron jobs.
- Improved the resolution of delivery failures and best-effort logic in the isolated agent's run function.
This update enhances the flexibility and reliability of delivery mechanisms in isolated cron jobs, ensuring better handling of message delivery scenarios.
* refactor(cron): improve delivery configuration handling in CronJobEditor and CLI
- Enhanced the delivery configuration logic in CronJobEditor to explicitly set the bestEffort property based on job settings.
- Refactored the CLI command to streamline delivery object creation, ensuring proper handling of optional fields like channel and to.
- Improved code readability and maintainability by restructuring delivery assignment logic.
This update clarifies the delivery configuration process, enhancing the reliability of job settings in both the editor and CLI.
* feat(cron): enhance legacy delivery handling in job patches
- Introduced logic to map legacy payload delivery updates onto the delivery object for `agentTurn` jobs, ensuring backward compatibility with legacy clients.
- Added tests to validate the correct application of legacy delivery settings in job patches, improving reliability in job configuration.
- Refactored delivery handling functions to streamline the merging of legacy delivery fields into the current job structure.
This update enhances the flexibility of delivery configurations, ensuring that legacy settings are properly handled in the context of new job patches.
* fix(cron): fix test failures and regenerate protocol files
- Add forceReload option to ensureLoaded to avoid stat I/O in normal
paths while still detecting cross-service writes in the timer path
- Post isolated job summary back to main session (restores the old
isolation.postToMainPrefix behavior via delivery model)
- Update legacy migration tests to check delivery.channel instead of
payload.channel (normalization now moves delivery fields to top-level)
- Remove legacy deliver/channel/to/bestEffortDeliver from payload schema
- Update protocol conformance test for delivery modes
- Regenerate GatewayModels.swift (isolation -> delivery)
* UI: handle future timestamps in formatAgo
* Changelog: move cron entries to 2026.2.3
* fix: cron announce delivery path (#8540) (thanks @tyler6204)
* Telegram: use Grammy types directly, add typed Probe/Audit to plugin interface (#8403)
* Telegram: replace duplicated types with Grammy imports, add Probe/Audit generics to plugin interface
* Telegram: remove legacy forward metadata (deprecated in Bot API 7.0), simplify required-field checks
* Telegram: clean up remaining legacy references and unnecessary casts
* Telegram: keep RequestInit parameter type in proxy fetch (addresses review feedback)
* Telegram: add exhaustiveness guard to resolveForwardOrigin switch
* fix(telegram): include forward_from_chat metadata in forwarded message context (#8133)
Extract missing metadata from forwarded Telegram messages:
- Add fromChatType to TelegramForwardedContext, capturing the original
chat type (channel/supergroup/group) from forward_from_chat.type
and forward_origin.chat/sender_chat.type
- Add fromMessageId to capture the original message ID from channel forwards
- Read author_signature from forward_origin objects (modern API),
preferring it over the deprecated forward_signature field
- Pass ForwardedFromChatType and ForwardedFromMessageId through to
the inbound context payload
- Add test coverage for forward_origin channel/chat types, including
author_signature extraction and fromChatType propagation
* fix: trim legacy signature fallback, type fromChatType as union
* fix: telegram forward metadata + cron delivery guard (#8392) (thanks @Glucksberg)
* fix(imessage): unify timeout configuration with configurable probeTimeoutMs
- Add probeTimeoutMs config option to channels.imessage
- Export DEFAULT_IMESSAGE_PROBE_TIMEOUT_MS constant (10s) from probe.ts
- Propagate timeout config through all iMessage probe/RPC operations
- Fix hardcoded 2000ms timeouts that were too short for SSH connections
Closes: timeout issues when using SSH wrapper scripts (imsg-ssh)
* fix: address review comments
- Use optional timeoutMs parameter (undefined = use config/default)
- Extract DEFAULT_IMESSAGE_PROBE_TIMEOUT_MS to shared constants.ts
- Import constant in client.ts instead of hardcoding
- Re-export constant from probe.ts for backwards compatibility
* fix(imessage): detect self-chat echoes to prevent infinite loops (#8680)
* fix: align proxy fetch typing
* feat: add cloudflare ai gateway provider
* fix: force reload cron store
* Revert "feat: Add Docs Chat Widget with RAG-powered Q&A (#7908)" (#8834)
This reverts commit fa4b28d7af7464b07271bfef6c028e4135548f44.
* fix(web ui): agent model selection
* Docs: landing page revamp (#8885)
* Docs: refresh landing page
* Docs: add landing page companion pages
* Docs: drop legacy Jekyll assets
* Docs: remove legacy terminal css test
* Docs: restore terminal css assets
* Docs: remove terminal css assets
* fix(app-render): handle optional model in renderApp function
* chore: replace landpr prompt with end-to-end landing workflow (#8916)
* 🤖 docs: mirror landing revamp for zh-CN
What:
- add zh-CN versions of landing revamp pages (features, quickstart, docs directory, network model, credits)
- refresh zh-CN index and hubs, plus glossary entries
Why:
- keep Chinese docs aligned with the new English landing experience
- ensure navigation surfaces the new entry points
Tests:
- pnpm build && pnpm check && pnpm test
* 🤖 docs: note zh-CN landing revamp (#8994) (thanks @joshp123)
What:
- add changelog entry for the zh-CN landing revamp docs
Why:
- record the doc update and thank the contributor
Tests:
- pnpm lint && pnpm build && pnpm test
* feat: add shell completion installation prompt to CLI update command
* feat: add shell completion test script for installation verification
* completion: export cache utilities and require cached file for installation
- Export `resolveCompletionCachePath` and `completionCacheExists` for external use
- Update `installCompletion` to require cache existence (never use slow dynamic pattern)
- Add `usesSlowDynamicCompletion` to detect old `source <(...)` patterns
- Add `getShellProfilePath` helper for consistent profile path resolution
- Update `formatCompletionSourceLine` to always use cached file
* doctor: add shell completion check module
- Add `checkShellCompletionStatus` to get profile/cache/slow-pattern status
- Add `ensureCompletionCacheExists` for silent cache regeneration
- Add `doctorShellCompletion` to check and fix completion issues:
- Auto-upgrade old slow dynamic patterns to cached version
- Auto-regenerate cache if profile exists but cache is missing
- Prompt to install if no completion is configured
* doctor: integrate shell completion check into doctor command
- Import and call `doctorShellCompletion` during doctor run
- Checks/fixes completion issues before gateway health check
* update: use shared completion helpers for shell completion setup
- Replace inline completion logic with `checkShellCompletionStatus` and `ensureCompletionCacheExists`
- Auto-upgrade old slow dynamic patterns silently during update
- Auto-regenerate cache if profile exists but cache is missing
- Prompt to install if no completion is configured
* onboard: use shared completion helpers for shell completion setup
- Replace inline completion logic with `checkShellCompletionStatus` and `ensureCompletionCacheExists`
- Auto-upgrade old slow dynamic patterns silently during onboarding
- Auto-regenerate cache if profile exists but cache is missing
- Prompt to install if no completion is configured
* scripts: update test-shell-completion to use shared helpers
- Use `checkShellCompletionStatus` and `ensureCompletionCacheExists` from doctor-completion
- Display "Uses slow pattern" status in output
- Simulate doctor/update/onboard behavior for all completion scenarios
- Remove duplicated utility functions
* changelog: add shell completion auto-fix entry
* feat: per-channel responsePrefix override (#9001)
* feat: per-channel responsePrefix override
Add responsePrefix field to all channel config types and Zod schemas,
enabling per-channel and per-account outbound response prefix overrides.
Resolution cascade (most specific wins):
L1: channels.<ch>.accounts.<id>.responsePrefix
L2: channels.<ch>.responsePrefix
L3: (reserved for channels.defaults)
L4: messages.responsePrefix (existing global)
Semantics:
- undefined -> inherit from parent level
- empty string -> explicitly no prefix (stops cascade)
- "auto" -> derive [identity.name] from routed agent
Changes:
- Core logic: resolveResponsePrefix() in identity.ts accepts
optional channel/accountId and walks the cascade
- resolveEffectiveMessagesConfig() passes channel context through
- Types: responsePrefix added to WhatsApp, Telegram, Discord, Slack,
Signal, iMessage, Google Chat, MS Teams, Feishu, BlueBubbles configs
- Zod schemas: responsePrefix added for config validation
- All channel handlers wired: telegram, discord, slack, signal,
imessage, line, heartbeat runner, route-reply, native commands
- 23 new tests covering backward compat, channel/account levels,
full cascade, auto keyword, empty string stops, unknown fallthrough
Fully backward compatible - no existing config is affected.
Fixes #8857
* fix: address CI lint + review feedback
- Replace Record<string, any> with proper typed helpers (no-explicit-any)
- Add curly braces to single-line if returns (eslint curly)
- Fix JSDoc: 'Per-channel' → 'channel/account' on shared config types
- Extract getChannelConfig() helper for type-safe dynamic key access
* fix: finish responsePrefix overrides (#9001) (thanks @mudrii)
* fix: normalize prefix wiring and types (#9001) (thanks @mudrii)
---------
Co-authored-by: Gustavo Madeira Santana <gumadeiras@gmail.com>
* Discord: allow disabling thread starter context
* feat(heartbeat): add accountId config option for multi-agent routing (#8702)
* feat(heartbeat): add accountId config option for multi-agent routing
Add optional accountId field to heartbeat configuration, allowing
multi-agent setups to explicitly specify which Telegram account
should be used for heartbeat delivery.
Previously, heartbeat delivery would use the accountId from the
session's deliveryContext. When a session had no prior conversation
history, heartbeats would default to the first/primary account
instead of the agent's intended bot.
Changes:
- Add accountId to HeartbeatSchema (zod-schema.agent-runtime.ts)
- Use heartbeat.accountId with fallback to session accountId (targets.ts)
Backward compatible: if accountId is not specified, behavior is unchanged.
Closes #8695
* fix: improve heartbeat accountId routing (#8702) (thanks @lsh411)
* fix: harden heartbeat accountId routing (#8702) (thanks @lsh411)
* fix: expose heartbeat accountId in status (#8702) (thanks @lsh411)
* chore: format status + heartbeat tests (#8702) (thanks @lsh411)
---------
Co-authored-by: m1 16 512 <m116512@m1ui-MacBookAir-2.local>
Co-authored-by: Gustavo Madeira Santana <gumadeiras@gmail.com>
* TUI/Gateway: fix pi streaming + tool routing + model display + msg updating (#8432)
* TUI/Gateway: fix pi streaming + tool routing
* Tests: clarify verbose tool output expectation
* fix: avoid seq gaps for targeted tool events (#8432) (thanks @gumadeiras)
* Telegram: remove @ts-nocheck from bot.ts, fix duplicate error handler, harden sticker caching (#9077)
* Telegram: remove @ts-nocheck from bot.ts and bot-message-dispatch.ts
- bot/types.ts: TelegramContext.me uses UserFromGetMe (Grammy) instead of manual inline type
- bot.ts: remove 6 unsafe casts (as any, as unknown, as object), use Grammy types directly
- bot.ts: remove dead message_thread_id access on reactions (not in Telegram Bot API)
- bot.ts: remove resolveThreadSessionKeys import (no longer needed for reactions)
- bot-message-dispatch.ts: replace ': any' with DispatchTelegramMessageParams type
- bot-message-dispatch.ts: add sticker.fileId guard before cache access
- bot.test.ts: update reaction tests, remove dead DM thread-reaction test
* Telegram: remove duplicate bot.catch handler (only the last one runs in Grammy)
* Telegram: remove @ts-nocheck from bot.ts, fix duplicate error handler, harden sticker caching (#9077)
* Security: Prevent gateway credential exfiltration via URL override (#9179)
* Gateway: require explicit auth for url overrides
* Gateway: scope credential blocking to non-local URLs only
Address review feedback: the previous fix blocked credential fallback for
ALL URL overrides, which was overly strict and could break workflows that
use --url to switch between loopback/tailnet without passing credentials.
Now credential fallback is only blocked for non-local URLs (public IPs,
external hostnames). Local addresses (127.0.0.1, localhost, private IPs
like 192.168.x.x, 10.x.x.x, tailnet 100.x.x.x) still get credential
fallback as before.
This maintains the security fix (preventing credential exfiltration to
attacker-controlled URLs) while preserving backward compatibility for
legitimate local URL overrides.
* Security: require explicit credentials for gateway url overrides (#8113) (thanks @victormier)
* Gateway: reuse explicit auth helper for url overrides (#8113) (thanks @victormier)
* Tests: format gateway chat test (#8113) (thanks @victormier)
* Tests: require explicit auth for gateway url overrides (#8113) (thanks @victormier)
---------
Co-authored-by: Victor Mier <victormier@gmail.com>
* Tests: restore TUI gateway env
* Security: harden sandboxed media handling (#9182)
* Message: enforce sandbox for media param
* fix: harden sandboxed media handling (#8780) (thanks @victormier)
* chore: format message action runner (#8780) (thanks @victormier)
---------
Co-authored-by: Victor Mier <victormier@gmail.com>
* Telegram: remove @ts-nocheck from bot-message.ts (#9180)
* Telegram: remove @ts-nocheck from bot-message.ts, type deps via Omit<BuildTelegramMessageContextParams>
* Telegram: widen allMedia to TelegramMediaRef[] so stickerMetadata flows through
* Telegram: remove @ts-nocheck from bot-message.ts (#9180)
* fix: cover anonymous voice allowlist callers (#8104) (thanks @victormier) (#9188)
* Security: owner-only tools + command auth hardening (#9202)
* Security: gate whatsapp_login by sender auth
* Security: treat undefined senderAuthorized as unauthorized (opt-in)
* fix: gate whatsapp_login to owner senders (#8768) (thanks @victormier)
* fix: add explicit owner allowlist for tools (#8768) (thanks @victormier)
* fix: normalize escaped newlines in send actions (#8768) (thanks @victormier)
---------
Co-authored-by: Victor Mier <victormier@gmail.com>
* Telegram: remove last @ts-nocheck from bot-handlers.ts (#9206)
* Telegram: remove @ts-nocheck from bot-handlers.ts, use Grammy types directly, deduplicate StickerMetadata
* Telegram: remove last @ts-nocheck from bot-handlers.ts (#9206)
* Message: clarify media schema + fix MEDIA newline
* fix: enforce owner allowlist for commands
* fix: infer --auth-choice from API key flags during non-interactive onboarding (#9241)
* fix: infer --auth-choice from API key flags during non-interactive onboarding
When --anthropic-api-key (or other provider key flags) is passed without
an explicit --auth-choice, the auth choice defaults to "skip", silently
discarding the API key. This means the gateway starts without credentials
and fails on every inbound message with "No API key found for provider".
Add inferAuthChoiceFromFlags() to derive the correct auth choice from
whichever provider API key flag was supplied, so credentials are persisted
to auth-profiles.json as expected.
Fixes #8481
* fix: infer auth choice from API key flags (#8484) (thanks @f-trycua)
* refactor: centralize auth choice inference flags (#8484) (thanks @f-trycua)
---------
Co-authored-by: f-trycua <f@trycua.com>
* chore: sync plugin versions to 2026.2.3
* fix(mac): resolve cron schedule formatters
* chore(mac): update appcast for 2026.2.3
* chore: update 2026.2.3 notes
---------
Co-authored-by: Ayaan Zaidi <zaidi@uplause.io>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: cpojer <christoph.pojer@gmail.com>
Co-authored-by: Christian Klotz <hello@christianklotz.co.uk>
Co-authored-by: Shadow <shadow@clawd.bot>
Co-authored-by: Josh Palmer <joshp123@users.noreply.github.com>
Co-authored-by: CLAWDINATOR Bot <clawdinator[bot]@users.noreply.github.com>
Co-authored-by: Marco Marandiz <admin-marco@Mac.lan>
Co-authored-by: Shakker <shakkerdroid@gmail.com>
Co-authored-by: Mariano Belinky <mariano@mb-server-643.local>
Co-authored-by: Mariano Belinky <mbelinky@gmail.com>
Co-authored-by: Tyler Yust <64381258+tyler6204@users.noreply.github.com>
Co-authored-by: Elarwei <elarweis@gmail.com>
Co-authored-by: bqcfjwhz85-arch <bqcfjwhz85@privaterelay.appleid.com>
Co-authored-by: lotusfall <lotusfall@outlook.com>
Co-authored-by: Ji <jizhang.work@gmail.com>
Co-authored-by: mac mimi <macmimi@macs-Mac-mini.local>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
Co-authored-by: Justin <justinhuangcode@gmail.com>
Co-authored-by: Aldo <hal@aldo.pw>
Co-authored-by: Gustavo Madeira Santana <gumadeiras@gmail.com>
Co-authored-by: Vignesh Natarajan <vigneshnatarajan92@gmail.com>
Co-authored-by: Benjamin Jesuiter <bjesuiter@gmail.com>
Co-authored-by: Ethan Palm <56270045+ethanpalm@users.noreply.github.com>
Co-authored-by: Armin Ronacher <armin.ronacher@active-4.com>
Co-authored-by: Josh Palmer <joshpalmer123@gmail.com>
Co-authored-by: Tyler Yust <TYTYYUST@YAHOO.COM>
Co-authored-by: Ermenegildo Fiorito <gildo.fiorito@gmail.com>
Co-authored-by: Michelle Tilley <michelle@michelletilley.net>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Stephen Chen <bochencleveland@yahoo.com>
Co-authored-by: stephenchen2025 <schenjobs@gmail.com>
Co-authored-by: Liu Weizhan <liu48566203@gmail.com>
Co-authored-by: Wangnov <48670012+Wangnov@users.noreply.github.com>
Co-authored-by: wangnov <1694546283@qq.com>
Co-authored-by: Yeom-JinHo <81306489+Yeom-JinHo@users.noreply.github.com>
Co-authored-by: Lucas Kim <ichbinlucas211@gmail.com>
Co-authored-by: Val Alexander <68980965+BunsDev@users.noreply.github.com>
Co-authored-by: Glucksberg <markuscontasul@gmail.com>
Co-authored-by: Yudong Han <hanyd@pku.edu.cn>
Co-authored-by: Iranb <49674669+Iranb@users.noreply.github.com>
Co-authored-by: Seb Slight <sebslight@gmail.com>
Co-authored-by: mudrii <mudreac@gmail.com>
Co-authored-by: lsh411 <lsh411@gmail.com>
Co-authored-by: m1 16 512 <m116512@m1ui-MacBookAir-2.local>
Co-authored-by: Gustavo Madeira Santana <gumadeiras@users.noreply.github.com>
Co-authored-by: Victor Mier <victormier@gmail.com>
Co-authored-by: f-trycua <f@trycua.com>
Co-authored-by: Nova <nova@noreply.github.com>
…interface (openclaw#8403) * Telegram: replace duplicated types with Grammy imports, add Probe/Audit generics to plugin interface * Telegram: remove legacy forward metadata (deprecated in Bot API 7.0), simplify required-field checks * Telegram: clean up remaining legacy references and unnecessary casts * Telegram: keep RequestInit parameter type in proxy fetch (addresses review feedback) * Telegram: add exhaustiveness guard to resolveForwardOrigin switch
…interface (openclaw#8403) * Telegram: replace duplicated types with Grammy imports, add Probe/Audit generics to plugin interface * Telegram: remove legacy forward metadata (deprecated in Bot API 7.0), simplify required-field checks * Telegram: clean up remaining legacy references and unnecessary casts * Telegram: keep RequestInit parameter type in proxy fetch (addresses review feedback) * Telegram: add exhaustiveness guard to resolveForwardOrigin switch
…interface (openclaw#8403) * Telegram: replace duplicated types with Grammy imports, add Probe/Audit generics to plugin interface * Telegram: remove legacy forward metadata (deprecated in Bot API 7.0), simplify required-field checks * Telegram: clean up remaining legacy references and unnecessary casts * Telegram: keep RequestInit parameter type in proxy fetch (addresses review feedback) * Telegram: add exhaustiveness guard to resolveForwardOrigin switch (cherry picked from commit da6de49) # Conflicts: # extensions/telegram/src/channel.ts # src/channels/plugins/types.adapters.ts # src/telegram/bot-native-commands.ts # src/telegram/bot-updates.ts # src/telegram/bot.ts # src/telegram/bot/helpers.test.ts # src/telegram/bot/helpers.ts
…interface (openclaw#8403) * Telegram: replace duplicated types with Grammy imports, add Probe/Audit generics to plugin interface * Telegram: remove legacy forward metadata (deprecated in Bot API 7.0), simplify required-field checks * Telegram: clean up remaining legacy references and unnecessary casts * Telegram: keep RequestInit parameter type in proxy fetch (addresses review feedback) * Telegram: add exhaustiveness guard to resolveForwardOrigin switch
…interface (openclaw#8403) * Telegram: replace duplicated types with Grammy imports, add Probe/Audit generics to plugin interface * Telegram: remove legacy forward metadata (deprecated in Bot API 7.0), simplify required-field checks * Telegram: clean up remaining legacy references and unnecessary casts * Telegram: keep RequestInit parameter type in proxy fetch (addresses review feedback) * Telegram: add exhaustiveness guard to resolveForwardOrigin switch
…interface (openclaw#8403) * Telegram: replace duplicated types with Grammy imports, add Probe/Audit generics to plugin interface * Telegram: remove legacy forward metadata (deprecated in Bot API 7.0), simplify required-field checks * Telegram: clean up remaining legacy references and unnecessary casts * Telegram: keep RequestInit parameter type in proxy fetch (addresses review feedback) * Telegram: add exhaustiveness guard to resolveForwardOrigin switch
…interface (openclaw#8403) * Telegram: replace duplicated types with Grammy imports, add Probe/Audit generics to plugin interface * Telegram: remove legacy forward metadata (deprecated in Bot API 7.0), simplify required-field checks * Telegram: clean up remaining legacy references and unnecessary casts * Telegram: keep RequestInit parameter type in proxy fetch (addresses review feedback) * Telegram: add exhaustiveness guard to resolveForwardOrigin switch
…interface (openclaw#8403) * Telegram: replace duplicated types with Grammy imports, add Probe/Audit generics to plugin interface * Telegram: remove legacy forward metadata (deprecated in Bot API 7.0), simplify required-field checks * Telegram: clean up remaining legacy references and unnecessary casts * Telegram: keep RequestInit parameter type in proxy fetch (addresses review feedback) * Telegram: add exhaustiveness guard to resolveForwardOrigin switch
* fix(control-ui): resolve header logo when gateway.controlUi.basePath is set (#7178)
* fix(control-ui): resolve header logo when gateway.controlUi.basePath is set
* refactor(control-ui): header logo under basePath; normalize logo URL with normalizeBasePath
* docs: add changelog for #7178 (thanks @Yeom-JinHo)
* docs: document secure DM mode preset (#7872)
* docs: document secure DM mode preset
* fix: resolve merge conflict in resizable-divider
* fix(security): separate untrusted channel metadata from system prompt (thanks @KonstantinMirin)
* docs: update Feishu plugin docs
* feat: Add Docs Chat Widget with RAG-powered Q&A (#7908)
* feat: add docs chat prototype and related scripts
- Introduced a minimal documentation chatbot that builds a search index from markdown files and serves responses via an API.
- Added scripts for building the index and serving the chat API.
- Updated package.json with new commands for chat index building and serving.
- Created a new Vercel configuration file for deployment.
- Added a README for the docs chat prototype detailing usage and integration.
* feat: enhance docs chat with vector-based RAG pipeline
- Added vector index building and serving capabilities to the docs chat.
- Introduced new scripts for generating embeddings and serving the chat API using vector search.
- Updated package.json with new commands for vector index operations.
- Enhanced README with instructions for the new RAG pipeline and legacy keyword pipeline.
- Removed outdated Vercel configuration file.
* feat: enhance chat widget with markdown rendering and style updates
- Integrated dynamic loading of markdown rendering for chat responses.
- Implemented a fallback for markdown rendering to ensure consistent display.
- Updated CSS variables for improved theming and visual consistency.
- Enhanced chat bubble and input styles for better user experience.
- Added new styles for markdown content in chat bubbles, including code blocks and lists.
* feat: add copy buttons to chat widget for enhanced user interaction
- Implemented copy buttons for chat responses and code blocks in the chat widget.
- Updated CSS styles for improved visibility and interaction of copy buttons.
- Adjusted textarea height for better user experience.
- Enhanced functionality to allow users to easily copy text from chat bubbles and code snippets.
* feat: update chat widget styles for improved user experience
- Changed accent color for better visibility.
- Enhanced preformatted text styles for code blocks, including padding and word wrapping.
- Adjusted positioning and styles of copy buttons for chat responses and code snippets.
- Improved hover effects for copy buttons to enhance interactivity.
* feat: enhance chat widget styles for better responsiveness and scrollbar design
- Updated chat panel dimensions for improved adaptability on various screen sizes.
- Added custom scrollbar styles for better aesthetics and usability.
- Adjusted chat bubble styles for enhanced visibility and interaction.
- Improved layout for expanded chat widget on smaller screens.
* feat: refine chat widget code block styles and copy button functionality
- Adjusted padding and margin for preformatted text in chat responses for better visual consistency.
- Introduced a compact style for single-line code blocks to enhance layout.
- Updated copy button logic to skip short code blocks, improving user experience when copying code snippets.
* feat: add resize handle functionality to chat widget for adjustable panel width
- Implemented a draggable resize handle for the chat widget's sidebar, allowing users to adjust the panel width.
- Added CSS styles for the resize handle, including hover effects and responsive behavior.
- Integrated drag-to-resize logic to maintain user-set width across interactions.
- Ensured the panel resets to default width when closed, enhancing user experience.
* feat: implement rate limiting and error handling in chat API
- Added rate limiting functionality to the chat API, allowing a maximum number of requests per IP within a specified time window.
- Implemented error handling for rate limit exceeded responses, including appropriate headers and retry instructions.
- Enhanced error handling for other API errors, providing user-friendly messages for various failure scenarios.
- Updated README to include new environment variables for rate limiting configuration.
* feat: integrate Upstash Vector for enhanced document retrieval in chat API
- Implemented Upstash Vector as a cloud-based storage solution for document chunks, replacing the local LanceDB option.
- Added auto-detection of storage mode based on environment variables for seamless integration.
- Updated the chat API to utilize the new retrieval mechanism, enhancing response accuracy and performance.
- Enhanced README with setup instructions for Upstash and updated environment variable requirements.
- Introduced new scripts and configurations for managing the vector index and API interactions.
* feat: add create-markdown-preview.js for markdown rendering
- Introduced a new script for framework-agnostic HTML rendering of markdown content.
- The script includes various parsing functions to handle different markdown elements.
- Updated the chat widget to load the vendored version of @create-markdown/preview for improved markdown rendering.
* docs: update README for Upstash Vector index setup and environment variables
- Enhanced instructions for creating a Vector index in Upstash, including detailed settings and important notes.
- Clarified environment variable requirements for both Upstash and LanceDB modes.
- Improved formatting and organization of setup steps for better readability.
- Added health check and API endpoint details for clearer usage guidance.
* feat: add TRUST_PROXY environment variable for IP address handling
- Introduced the TRUST_PROXY variable to control the trust of X-Forwarded-For headers when behind a reverse proxy.
- Updated the README to document the new environment variable and its default value.
- Enhanced the getClientIP function to conditionally trust proxy headers based on the TRUST_PROXY setting.
* feat: add ALLOWED_ORIGINS environment variable for CORS configuration
- Introduced the ALLOWED_ORIGINS variable to specify allowed origins for CORS, enhancing security and flexibility.
- Updated the README to document the new environment variable and its usage.
- Refactored CORS handling in the server code to utilize the ALLOWED_ORIGINS setting for dynamic origin control.
* fix: ensure complete markdown rendering in chat widget
- Added logic to flush any remaining buffered bytes from the decoder, ensuring that all text is rendered correctly in the assistant bubble.
- Updated the assistant bubble's innerHTML to reflect the complete markdown content after streaming completes.
* feat: enhance DocsStore with improved vector handling and similarity conversion
- Added a constant for the distance metric used in vector searches, clarifying the assumption of L2 distance.
- Updated the createTable method to ensure all chunk properties are correctly mapped during table creation.
- Improved the similarity score calculation by providing a clear explanation of the conversion from L2 distance, ensuring accurate ranking of results.
* chore: fix code formatting
* Revert "chore: fix code formatting"
This reverts commit 6721f5b0b7bf60b76c519ccadfa41742f19ecf87.
* chore: format code for improved readability
- Reformatted code in serve.ts to enhance readability by adjusting indentation and line breaks.
- Ensured consistent style for function return types and object properties throughout the file.
* feat: Update API URL selection logic in chat widget
- Enhanced the API URL configuration to prioritize explicit settings, defaulting to localhost for development and using a production URL otherwise.
- Improved clarity in the code by adding comments to explain the logic behind the API URL selection.
* chore: Update documentation structure for improved organization
- Changed the path for the "Start Here" page to "start/index" for better clarity.
- Reformatted the "Web & Interfaces" and "Help" groups to use multi-line arrays for improved readability.
* feat: Enhance markdown preview integration and improve chat widget asset loading
- Wrapped the markdown preview functionality in an IIFE to expose a global API for easier integration.
- Updated the chat widget to load the markdown preview library dynamically, checking for existing instances to avoid duplicate loads.
- Adjusted asset paths in the chat widget to ensure correct loading based on the environment (local or production).
- Added CORS headers in the Vercel configuration for improved API accessibility.
* fix: Update chat API URL to include '/api' for correct endpoint access
- Modified the chat configuration and widget files to append '/api' to the API URL, ensuring proper endpoint usage in production and local environments.
* refactor: Simplify docs-chat configuration and remove unused scripts
- Removed outdated scripts and configurations related to the docs-chat feature, including build and serve scripts, as well as the associated package.json and README files.
- Streamlined the API URL configuration in the chat widget for better clarity and maintainability.
- Updated the package.json to remove unnecessary scripts related to the now-deleted functionality.
* refactor: Update documentation structure for improved clarity
- Changed the path for the "Start Here" page from "start/index" to "index" to enhance navigation and organization within the documentation.
* chore: Remove unused dependencies from package.json and pnpm-lock.yaml
- Deleted `@lancedb/lancedb`, `@upstash/vector`, and `openai` from both package.json and pnpm-lock.yaml to streamline the project and reduce bloat.
* chore: Clean up .gitignore by removing obsolete entries
- Deleted unused entries related to the docs-chat vector database from .gitignore to maintain a cleaner configuration.
* chore: Remove deprecated chat configuration and markdown preview script
- Deleted the `create-markdown-preview.js` script and the `docs-chat-config.js` file to eliminate unused assets and streamline the project.
- Updated the `docs-chat-widget.js` to directly reference the markdown library from a CDN, enhancing maintainability.
* chore: Update markdown rendering in chat widget to use marked library
- Replaced the deprecated `create-markdown-preview` library with the `marked` library for markdown rendering.
- Adjusted the script loading mechanism to fetch `marked` from a CDN, improving performance and maintainability.
- Enhanced the markdown rendering function to ensure security by disabling HTML pass-through and opening links in new tabs.
* Delete docs/start/index.md
* fix: harden voice-call webhook verification
* fix(cron): fix timeout, add timestamp validation, enable file sync
Fixes #7667
Task 1: Fix cron operation timeouts
- Increase default gateway tool timeout from 10s to 30s
- Increase cron-specific tool timeout to 60s
- Increase CLI default timeout from 10s to 30s
- Prevents timeouts when gateway is busy with long-running jobs
Task 2: Add timestamp validation
- New validateScheduleTimestamp() function in validate-timestamp.ts
- Rejects atMs timestamps more than 1 minute in the past
- Rejects atMs timestamps more than 10 years in the future
- Applied to both cron.add and cron.update operations
- Provides helpful error messages with current time and offset
Task 3: Enable file sync for manual edits
- Track file modification time (storeFileMtimeMs) in CronServiceState
- Check file mtime in ensureLoaded() and reload if changed
- Recompute next runs after reload to maintain accuracy
- Update mtime after persist() to prevent reload loop
- Dashboard now picks up manual edits to ~/.openclaw/cron/jobs.json
* feat(cron): introduce delivery modes for isolated jobs
- Added support for new delivery modes in cron jobs: `announce`, `deliver`, and `none`.
- Updated documentation to reflect changes in delivery options and usage examples.
- Enhanced the cron job schema to include delivery configuration.
- Refactored related CLI commands and UI components to accommodate the new delivery settings.
- Improved handling of legacy delivery fields for backward compatibility.
This update allows users to choose how output from isolated jobs is delivered, enhancing flexibility in job management.
* feat(cron): default isolated jobs to announce delivery and enhance scheduling options
- Updated isolated cron jobs to default to `announce` delivery mode, improving user experience.
- Enhanced scheduling options to accept ISO 8601 timestamps for `schedule.at`, while still supporting epoch milliseconds.
- Refined documentation to clarify delivery modes and scheduling formats.
- Adjusted related CLI commands and UI components to reflect these changes, ensuring consistency across the platform.
- Improved handling of legacy delivery fields for backward compatibility.
This update streamlines the configuration of isolated jobs, making it easier for users to manage job outputs and schedules.
* feat(cron): enhance one-shot job behavior and CLI options
- Default one-shot jobs to delete after success, improving job management.
- Introduced `--keep-after-run` CLI option to allow users to retain one-shot jobs post-execution.
- Updated documentation to clarify default behaviors and new options for one-shot jobs.
- Adjusted cron job creation logic to ensure consistent handling of delete options.
- Enhanced tests to validate new behaviors and ensure reliability.
This update streamlines the handling of one-shot jobs, providing users with more control over job persistence and execution outcomes.
* feat(cron): enhance delivery modes and job configuration
- Updated isolated cron jobs to support new delivery modes: `announce` and `none`, improving output management.
- Refactored job configuration to remove legacy fields and streamline delivery settings.
- Enhanced the `CronJobEditor` UI to reflect changes in delivery options, including a new segmented control for delivery mode selection.
- Updated documentation to clarify the new delivery configurations and their implications for job execution.
- Improved tests to validate the new delivery behavior and ensure backward compatibility with legacy settings.
This update provides users with greater flexibility in managing how isolated jobs deliver their outputs, enhancing overall usability and clarity in job configurations.
* feat(cron): set default enabled state for cron jobs
- Added logic to default the `enabled` property to `true` if not explicitly set as a boolean in the cron job input.
- Updated job creation and store functions to ensure consistent handling of the `enabled` state across the application.
- Enhanced input normalization to improve job configuration reliability.
This update ensures that cron jobs are enabled by default, enhancing user experience and reducing potential misconfigurations.
* refactor(cron): update delivery instructions for isolated agent
- Revised the delivery instructions in the isolated agent's command body to clarify that summaries should be returned as plain text and will be delivered by the main agent.
- Removed the previous directive regarding messaging tools to streamline communication guidelines.
This change enhances clarity in the delivery process for isolated agent tasks.
* feat(cron): enhance delivery handling and testing for isolated jobs
- Introduced new properties for explicit message targeting and message tool disabling in the EmbeddedRunAttemptParams type.
- Updated cron job tests to validate best-effort delivery behavior and handling of delivery failures.
- Added logic to clear delivery settings when switching session targets in cron jobs.
- Improved the resolution of delivery failures and best-effort logic in the isolated agent's run function.
This update enhances the flexibility and reliability of delivery mechanisms in isolated cron jobs, ensuring better handling of message delivery scenarios.
* refactor(cron): improve delivery configuration handling in CronJobEditor and CLI
- Enhanced the delivery configuration logic in CronJobEditor to explicitly set the bestEffort property based on job settings.
- Refactored the CLI command to streamline delivery object creation, ensuring proper handling of optional fields like channel and to.
- Improved code readability and maintainability by restructuring delivery assignment logic.
This update clarifies the delivery configuration process, enhancing the reliability of job settings in both the editor and CLI.
* feat(cron): enhance legacy delivery handling in job patches
- Introduced logic to map legacy payload delivery updates onto the delivery object for `agentTurn` jobs, ensuring backward compatibility with legacy clients.
- Added tests to validate the correct application of legacy delivery settings in job patches, improving reliability in job configuration.
- Refactored delivery handling functions to streamline the merging of legacy delivery fields into the current job structure.
This update enhances the flexibility of delivery configurations, ensuring that legacy settings are properly handled in the context of new job patches.
* fix(cron): fix test failures and regenerate protocol files
- Add forceReload option to ensureLoaded to avoid stat I/O in normal
paths while still detecting cross-service writes in the timer path
- Post isolated job summary back to main session (restores the old
isolation.postToMainPrefix behavior via delivery model)
- Update legacy migration tests to check delivery.channel instead of
payload.channel (normalization now moves delivery fields to top-level)
- Remove legacy deliver/channel/to/bestEffortDeliver from payload schema
- Update protocol conformance test for delivery modes
- Regenerate GatewayModels.swift (isolation -> delivery)
* UI: handle future timestamps in formatAgo
* Changelog: move cron entries to 2026.2.3
* fix: cron announce delivery path (#8540) (thanks @tyler6204)
* Telegram: use Grammy types directly, add typed Probe/Audit to plugin interface (#8403)
* Telegram: replace duplicated types with Grammy imports, add Probe/Audit generics to plugin interface
* Telegram: remove legacy forward metadata (deprecated in Bot API 7.0), simplify required-field checks
* Telegram: clean up remaining legacy references and unnecessary casts
* Telegram: keep RequestInit parameter type in proxy fetch (addresses review feedback)
* Telegram: add exhaustiveness guard to resolveForwardOrigin switch
* fix(telegram): include forward_from_chat metadata in forwarded message context (#8133)
Extract missing metadata from forwarded Telegram messages:
- Add fromChatType to TelegramForwardedContext, capturing the original
chat type (channel/supergroup/group) from forward_from_chat.type
and forward_origin.chat/sender_chat.type
- Add fromMessageId to capture the original message ID from channel forwards
- Read author_signature from forward_origin objects (modern API),
preferring it over the deprecated forward_signature field
- Pass ForwardedFromChatType and ForwardedFromMessageId through to
the inbound context payload
- Add test coverage for forward_origin channel/chat types, including
author_signature extraction and fromChatType propagation
* fix: trim legacy signature fallback, type fromChatType as union
* fix: telegram forward metadata + cron delivery guard (#8392) (thanks @Glucksberg)
* fix(imessage): unify timeout configuration with configurable probeTimeoutMs
- Add probeTimeoutMs config option to channels.imessage
- Export DEFAULT_IMESSAGE_PROBE_TIMEOUT_MS constant (10s) from probe.ts
- Propagate timeout config through all iMessage probe/RPC operations
- Fix hardcoded 2000ms timeouts that were too short for SSH connections
Closes: timeout issues when using SSH wrapper scripts (imsg-ssh)
* fix: address review comments
- Use optional timeoutMs parameter (undefined = use config/default)
- Extract DEFAULT_IMESSAGE_PROBE_TIMEOUT_MS to shared constants.ts
- Import constant in client.ts instead of hardcoding
- Re-export constant from probe.ts for backwards compatibility
* fix(imessage): detect self-chat echoes to prevent infinite loops (#8680)
* fix: align proxy fetch typing
* feat: add cloudflare ai gateway provider
* fix: force reload cron store
* Revert "feat: Add Docs Chat Widget with RAG-powered Q&A (#7908)" (#8834)
This reverts commit fa4b28d7af7464b07271bfef6c028e4135548f44.
* fix(web ui): agent model selection
* Docs: landing page revamp (#8885)
* Docs: refresh landing page
* Docs: add landing page companion pages
* Docs: drop legacy Jekyll assets
* Docs: remove legacy terminal css test
* Docs: restore terminal css assets
* Docs: remove terminal css assets
* fix(app-render): handle optional model in renderApp function
* chore: replace landpr prompt with end-to-end landing workflow (#8916)
* 🤖 docs: mirror landing revamp for zh-CN
What:
- add zh-CN versions of landing revamp pages (features, quickstart, docs directory, network model, credits)
- refresh zh-CN index and hubs, plus glossary entries
Why:
- keep Chinese docs aligned with the new English landing experience
- ensure navigation surfaces the new entry points
Tests:
- pnpm build && pnpm check && pnpm test
* 🤖 docs: note zh-CN landing revamp (#8994) (thanks @joshp123)
What:
- add changelog entry for the zh-CN landing revamp docs
Why:
- record the doc update and thank the contributor
Tests:
- pnpm lint && pnpm build && pnpm test
* feat: add shell completion installation prompt to CLI update command
* feat: add shell completion test script for installation verification
* completion: export cache utilities and require cached file for installation
- Export `resolveCompletionCachePath` and `completionCacheExists` for external use
- Update `installCompletion` to require cache existence (never use slow dynamic pattern)
- Add `usesSlowDynamicCompletion` to detect old `source <(...)` patterns
- Add `getShellProfilePath` helper for consistent profile path resolution
- Update `formatCompletionSourceLine` to always use cached file
* doctor: add shell completion check module
- Add `checkShellCompletionStatus` to get profile/cache/slow-pattern status
- Add `ensureCompletionCacheExists` for silent cache regeneration
- Add `doctorShellCompletion` to check and fix completion issues:
- Auto-upgrade old slow dynamic patterns to cached version
- Auto-regenerate cache if profile exists but cache is missing
- Prompt to install if no completion is configured
* doctor: integrate shell completion check into doctor command
- Import and call `doctorShellCompletion` during doctor run
- Checks/fixes completion issues before gateway health check
* update: use shared completion helpers for shell completion setup
- Replace inline completion logic with `checkShellCompletionStatus` and `ensureCompletionCacheExists`
- Auto-upgrade old slow dynamic patterns silently during update
- Auto-regenerate cache if profile exists but cache is missing
- Prompt to install if no completion is configured
* onboard: use shared completion helpers for shell completion setup
- Replace inline completion logic with `checkShellCompletionStatus` and `ensureCompletionCacheExists`
- Auto-upgrade old slow dynamic patterns silently during onboarding
- Auto-regenerate cache if profile exists but cache is missing
- Prompt to install if no completion is configured
* scripts: update test-shell-completion to use shared helpers
- Use `checkShellCompletionStatus` and `ensureCompletionCacheExists` from doctor-completion
- Display "Uses slow pattern" status in output
- Simulate doctor/update/onboard behavior for all completion scenarios
- Remove duplicated utility functions
* changelog: add shell completion auto-fix entry
* feat: per-channel responsePrefix override (#9001)
* feat: per-channel responsePrefix override
Add responsePrefix field to all channel config types and Zod schemas,
enabling per-channel and per-account outbound response prefix overrides.
Resolution cascade (most specific wins):
L1: channels.<ch>.accounts.<id>.responsePrefix
L2: channels.<ch>.responsePrefix
L3: (reserved for channels.defaults)
L4: messages.responsePrefix (existing global)
Semantics:
- undefined -> inherit from parent level
- empty string -> explicitly no prefix (stops cascade)
- "auto" -> derive [identity.name] from routed agent
Changes:
- Core logic: resolveResponsePrefix() in identity.ts accepts
optional channel/accountId and walks the cascade
- resolveEffectiveMessagesConfig() passes channel context through
- Types: responsePrefix added to WhatsApp, Telegram, Discord, Slack,
Signal, iMessage, Google Chat, MS Teams, Feishu, BlueBubbles configs
- Zod schemas: responsePrefix added for config validation
- All channel handlers wired: telegram, discord, slack, signal,
imessage, line, heartbeat runner, route-reply, native commands
- 23 new tests covering backward compat, channel/account levels,
full cascade, auto keyword, empty string stops, unknown fallthrough
Fully backward compatible - no existing config is affected.
Fixes #8857
* fix: address CI lint + review feedback
- Replace Record<string, any> with proper typed helpers (no-explicit-any)
- Add curly braces to single-line if returns (eslint curly)
- Fix JSDoc: 'Per-channel' → 'channel/account' on shared config types
- Extract getChannelConfig() helper for type-safe dynamic key access
* fix: finish responsePrefix overrides (#9001) (thanks @mudrii)
* fix: normalize prefix wiring and types (#9001) (thanks @mudrii)
---------
Co-authored-by: Gustavo Madeira Santana <gumadeiras@gmail.com>
* Discord: allow disabling thread starter context
* feat(heartbeat): add accountId config option for multi-agent routing (#8702)
* feat(heartbeat): add accountId config option for multi-agent routing
Add optional accountId field to heartbeat configuration, allowing
multi-agent setups to explicitly specify which Telegram account
should be used for heartbeat delivery.
Previously, heartbeat delivery would use the accountId from the
session's deliveryContext. When a session had no prior conversation
history, heartbeats would default to the first/primary account
instead of the agent's intended bot.
Changes:
- Add accountId to HeartbeatSchema (zod-schema.agent-runtime.ts)
- Use heartbeat.accountId with fallback to session accountId (targets.ts)
Backward compatible: if accountId is not specified, behavior is unchanged.
Closes #8695
* fix: improve heartbeat accountId routing (#8702) (thanks @lsh411)
* fix: harden heartbeat accountId routing (#8702) (thanks @lsh411)
* fix: expose heartbeat accountId in status (#8702) (thanks @lsh411)
* chore: format status + heartbeat tests (#8702) (thanks @lsh411)
---------
Co-authored-by: m1 16 512 <m116512@m1ui-MacBookAir-2.local>
Co-authored-by: Gustavo Madeira Santana <gumadeiras@gmail.com>
* TUI/Gateway: fix pi streaming + tool routing + model display + msg updating (#8432)
* TUI/Gateway: fix pi streaming + tool routing
* Tests: clarify verbose tool output expectation
* fix: avoid seq gaps for targeted tool events (#8432) (thanks @gumadeiras)
* Telegram: remove @ts-nocheck from bot.ts, fix duplicate error handler, harden sticker caching (#9077)
* Telegram: remove @ts-nocheck from bot.ts and bot-message-dispatch.ts
- bot/types.ts: TelegramContext.me uses UserFromGetMe (Grammy) instead of manual inline type
- bot.ts: remove 6 unsafe casts (as any, as unknown, as object), use Grammy types directly
- bot.ts: remove dead message_thread_id access on reactions (not in Telegram Bot API)
- bot.ts: remove resolveThreadSessionKeys import (no longer needed for reactions)
- bot-message-dispatch.ts: replace ': any' with DispatchTelegramMessageParams type
- bot-message-dispatch.ts: add sticker.fileId guard before cache access
- bot.test.ts: update reaction tests, remove dead DM thread-reaction test
* Telegram: remove duplicate bot.catch handler (only the last one runs in Grammy)
* Telegram: remove @ts-nocheck from bot.ts, fix duplicate error handler, harden sticker caching (#9077)
* Security: Prevent gateway credential exfiltration via URL override (#9179)
* Gateway: require explicit auth for url overrides
* Gateway: scope credential blocking to non-local URLs only
Address review feedback: the previous fix blocked credential fallback for
ALL URL overrides, which was overly strict and could break workflows that
use --url to switch between loopback/tailnet without passing credentials.
Now credential fallback is only blocked for non-local URLs (public IPs,
external hostnames). Local addresses (127.0.0.1, localhost, private IPs
like 192.168.x.x, 10.x.x.x, tailnet 100.x.x.x) still get credential
fallback as before.
This maintains the security fix (preventing credential exfiltration to
attacker-controlled URLs) while preserving backward compatibility for
legitimate local URL overrides.
* Security: require explicit credentials for gateway url overrides (#8113) (thanks @victormier)
* Gateway: reuse explicit auth helper for url overrides (#8113) (thanks @victormier)
* Tests: format gateway chat test (#8113) (thanks @victormier)
* Tests: require explicit auth for gateway url overrides (#8113) (thanks @victormier)
---------
Co-authored-by: Victor Mier <victormier@gmail.com>
* Tests: restore TUI gateway env
* Security: harden sandboxed media handling (#9182)
* Message: enforce sandbox for media param
* fix: harden sandboxed media handling (#8780) (thanks @victormier)
* chore: format message action runner (#8780) (thanks @victormier)
---------
Co-authored-by: Victor Mier <victormier@gmail.com>
* Telegram: remove @ts-nocheck from bot-message.ts (#9180)
* Telegram: remove @ts-nocheck from bot-message.ts, type deps via Omit<BuildTelegramMessageContextParams>
* Telegram: widen allMedia to TelegramMediaRef[] so stickerMetadata flows through
* Telegram: remove @ts-nocheck from bot-message.ts (#9180)
* fix: cover anonymous voice allowlist callers (#8104) (thanks @victormier) (#9188)
* Security: owner-only tools + command auth hardening (#9202)
* Security: gate whatsapp_login by sender auth
* Security: treat undefined senderAuthorized as unauthorized (opt-in)
* fix: gate whatsapp_login to owner senders (#8768) (thanks @victormier)
* fix: add explicit owner allowlist for tools (#8768) (thanks @victormier)
* fix: normalize escaped newlines in send actions (#8768) (thanks @victormier)
---------
Co-authored-by: Victor Mier <victormier@gmail.com>
* Telegram: remove last @ts-nocheck from bot-handlers.ts (#9206)
* Telegram: remove @ts-nocheck from bot-handlers.ts, use Grammy types directly, deduplicate StickerMetadata
* Telegram: remove last @ts-nocheck from bot-handlers.ts (#9206)
* Message: clarify media schema + fix MEDIA newline
* fix: enforce owner allowlist for commands
* fix: infer --auth-choice from API key flags during non-interactive onboarding (#9241)
* fix: infer --auth-choice from API key flags during non-interactive onboarding
When --anthropic-api-key (or other provider key flags) is passed without
an explicit --auth-choice, the auth choice defaults to "skip", silently
discarding the API key. This means the gateway starts without credentials
and fails on every inbound message with "No API key found for provider".
Add inferAuthChoiceFromFlags() to derive the correct auth choice from
whichever provider API key flag was supplied, so credentials are persisted
to auth-profiles.json as expected.
Fixes #8481
* fix: infer auth choice from API key flags (#8484) (thanks @f-trycua)
* refactor: centralize auth choice inference flags (#8484) (thanks @f-trycua)
---------
Co-authored-by: f-trycua <f@trycua.com>
* chore: sync plugin versions to 2026.2.3
* fix(mac): resolve cron schedule formatters
* chore(mac): update appcast for 2026.2.3
* chore: update 2026.2.3 notes
* fix: gracefully downgrade xhigh thinking level in cron isolated agent (#9363)
When thinkingDefault is set to "xhigh" but the configured model does not
support it (e.g. Claude), the cron isolated-agent path throws a hard error
causing the job to fail. The interactive chat path already handles this by
silently downgrading to "high".
Apply the same graceful downgrade in the cron path: log a warning and
fall back to "high" instead of crashing.
Co-authored-by: hyf0-agent <hyf0-agent@users.noreply.github.com>
* fix: restore discord owner hint from allowlists
* fix: remove unused cron import
* fix(cli): resolve bundled chrome extension path
* test(cli): use unique temp dir for extension install
* fix(cli): support bundled extension path in dist root
* style(cli): satisfy lint rules in extension path resolver
* fix: resolve bundled chrome extension assets (#8914) (thanks @kelvinCB)
* Tests: add test coverage for security/windows-acl.ts
Adds comprehensive unit tests for Windows ACL inspection utilities:
- resolveWindowsUserPrincipal: username resolution with fallback
- parseIcaclsOutput: icacls output parsing
- summarizeWindowsAcl: ACL entry classification (trusted/world/group)
- inspectWindowsAcl: async ACL inspection with mocked exec
- formatWindowsAclSummary: summary string formatting
- formatIcaclsResetCommand: reset command string generation
- createIcaclsResetCommand: structured reset command generation
All 26 tests passing.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: stabilize windows acl tests and command auth registry (#9335) (thanks @M00N7682)
* test: register discord plugin in allowlist test
* chore: bump version to 2026.2.4
* fix: resolve discord owner allowFrom matches
* fix(telegram): preserve DM topic threadId in deliveryContext
When receiving messages in Telegram DM topics (Topics in Private Chats),
the threadId was not saved in the session's deliveryContext, causing
replies to go to General chat instead of the topic.
Now we pass threadId to updateLastRoute for DM topics.
Fixes #8891
* test(telegram): add DM topic threadId deliveryContext test for #8891
Verifies that threadId is passed to updateLastRoute for DM topics.
Test fails on main branch, passes with the fix.
* fix: preserve telegram DM topic threadId (#9039) (thanks @lailoo)
* Update deps.
* chore: Typecheck test helper files.
* Docs: streamline start and install docs (#9648)
* docs(start): streamline getting started flow
* docs(nav): reorganize start and install sections
* docs(style): move custom css to style.css
* docs(navigation): align zh-CN ordering
* docs(navigation): localize zh-Hans labels
* docs(install): rename install overview page
* CLI: sort commands alphabetically in help output
Fixes #7964
Added sortSubcommands: true to configureHelp() to display
commands in alphabetical order when running 'openclaw --help'.
* fix: update changelog for help sorting (#8068) (thanks @deepsoumya617)
* docs(onboarding): add bootstrapping page (#9767)
* docs: fix onboarding rendering issues
* chore: reset appcast to 2026.2.3
* fix(telegram): pass parentPeer for forum topic binding inheritance (#9789)
Fixes #9545 and #9351.
When a message comes from a Telegram forum topic, the peer ID includes
the topic suffix (e.g., `-1001234567890:topic:99`). Users configure
bindings with the base group ID, which previously did not match.
This adds `parentPeer` to `resolveAgentRoute()` calls for forum groups,
enabling binding inheritance from the parent group to all topics.
- Extract `buildTelegramParentPeer()` helper in bot/helpers.ts
- Pass parentPeer in bot-message-context.ts, bot-handlers.ts,
bot-native-commands.ts, and bot.ts (reaction handler)
- Add tests for forum topic routing and topic precedence
* docs(onboarding): streamline CLI onboarding docs (#9830)
* fix: auto-inject Telegram forum topic threadId in message tool
When using Telegram DM topics (forum topics), messages sent via the
message tool (media, buttons, etc.) land in General Topic instead of
the user's current topic. This happens because Slack has
resolveSlackAutoThreadId for auto-threading but Telegram had no
equivalent.
Add resolveTelegramAutoThreadId that mirrors the Slack pattern:
- When channel is telegram and no explicit threadId is provided
- Check if toolContext.currentThreadTs (the topic ID) is set
- Verify the target matches the originating chat
- Inject the threadId into params so the Telegram plugin action
handler picks it up for sendMessage/sendMedia
The subagent announce path already correctly passes threadId via
requesterOrigin (set from agentThreadId in sessions-spawn-tool),
so no changes needed there.
* test: cover telegram topic threadId auto-injection and subagent origin threading
* fix: pass threadId/to/accountId from parent to subagent gateway call
When spawning a subagent, the requesterOrigin's threadId, to, and
accountId were not forwarded to the callGateway({method:'agent'}) params.
This meant the subagent's runContext had no currentThreadTs or
currentChannelId, so resolveTelegramAutoThreadId could not auto-inject
the forum topic thread ID when the subagent used the message tool.
Changes:
- sessions-spawn-tool: pass to, accountId, threadId from requesterOrigin
- run-context: populate currentChannelId from opts.to as fallback
Fixes subagent messages landing in General Topic instead of the correct
Telegram DM topic thread.
* fix: telegram topic auto-threading — use parseTelegramTarget, add tests (#7235) (thanks @Lukavyi)
* update handle
* docs: fix incorrect model.fallback to model.fallbacks in Ollama config (#9384) (#9749)
Both English and Chinese documentation had incorrect configuration template
using 'fallback' instead of 'fallbacks' in agents.defaults.model config.
Co-authored-by: damaozi <1811866786@qq.com>
* fix(cli): avoid NODE_OPTIONS for --disable-warning (#9691) (thanks @18-RAJAT)
Fixes npm pack failing on modern Node where --disable-warning is disallowed in NODE_OPTIONS.
* feat: add Claude Opus 4.6 to built-in model catalog (#9853)
* feat: add Claude Opus 4.6 to built-in model catalog
- Update default model from claude-opus-4-5 to claude-opus-4-6
- Add opus-4.6 model ID normalization
- Add claude-opus-4-6 to live model filter prefixes
- Update image tool to prefer claude-opus-4-6 for vision
- Add CLI backend alias for opus-4.6
- Update onboard auth default selections to include opus-4.6
- Update model picker placeholder
Closes #9811
* test: update tests for claude-opus-4-6 default
- Fix model-alias-defaults test to use claude-opus-4-6
- Fix image-tool test to expect claude-opus-4-6 in fallbacks
* feat: support claude-opus-4-6
* docs: update changelog for opus 4.6 (#9853) (thanks @TinyTb)
* chore: bump pi to 0.52.0
---------
Co-authored-by: Slurpy <slurpy@openclaw.ai>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
* 🤖 Feishu: expand channel support
What:
- add post parsing, doc link extraction, routing, replies, reactions, typing, and user lookup
- fix media download/send flows and make doc fetches domain-aware
- update Feishu docs and clawtributor credits
Why:
- raise Feishu parity with other channels and avoid dropped group messages
- keep replies threaded while supporting Lark domains
- document new configuration and credit the contributor
Tests:
- pnpm build
- pnpm check
- pnpm test (gateway suite timed out; reran pnpm vitest run --config vitest.gateway.config.ts)
Co-authored-by: 九灵云 <server@jiulingyun.cn>
* 🤖 Feishu: tighten mention gating
What:
- require the bot open_id match for group mention detection when available
Why:
- prevent replies when other users are mentioned and the bot id is known
Tests:
- pnpm test
* fix: remove orphaned tool_results during compaction pruning
When pruneHistoryForContextShare drops chunks of messages, it could drop
an assistant message with tool_use blocks while leaving corresponding
tool_result messages in the kept portion. These orphaned tool_results
cause Anthropic's API to reject the session with 'unexpected tool_use_id'.
Fix by calling repairToolUseResultPairing after each chunk drop to clean
up any orphaned tool_results. This reuses existing battle-tested code
from session-transcript-repair.ts.
Fixes #9769, #9724, #9672
* fix cron scheduling and reminder delivery regressions (#9733)
* fix(cron): prevent timer from allowing process exit (fixes #9694)
The cron timer was using .unref(), which caused the Node.js event
loop to exit or sleep if no other handles were active. This prevented
cron jobs from firing in some environments.
* fix(cron): infer delivery target for isolated jobs (fixes #9683)
When creating isolated agentTurn jobs (e.g. reminders) without explicit
delivery options, the job would default to 'announce' but fail to
resolve the target conversation. Now, we infer the channel and
recipient from the agent's current session key.
* fix(cron): enhance delivery inference for threaded sessions and null inputs (#9733)
Improves the delivery inference logic in the cron tool to correctly handle threaded session keys and cases where delivery is explicitly set to null. This ensures that the appropriate delivery mode and target are inferred based on the agent's session key, enhancing the reliability of job execution.
* fix: preserve telegram topic delivery inference (#9733) (thanks @tyler6204)
* fix: simplify cron delivery merge spread (#9733) (thanks @tyler6204)
* chore: add agent credentials to gitignore (#9874)
Protect sensitive files from accidental commit:
- memory/ (moltbook credentials, session data)
- .agent/*.json (agent config, moltbook.json)
Workflows in .agent/workflows/ remain tracked.
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* Docs: escape hash symbol in help channel names in issue template (#9695)
* feat(skills): add QR code skill (#8817)
feat(skills): add QR code generation and reading skill
Adds qr-code skill with:
- qr_generate.py - Generate QR codes with customizable size/error correction
- qr_read.py - Decode QR codes from images
- SKILL.md documentation
Co-authored-by: Omar-Khaleel
* chore(agentsmd): add tsgo command to AGENTS.md (#9894)
Add `pnpm tsgo` command to AGENTS.md development reference
Co-authored-by: vincentkoc <vincentkoc@users.noreply.github.com>
* fix(runtime): bump minimum Node.js version to 22.12.0 (#5370)
* fix(runtime): bump minimum Node.js version to 22.12.0
Aligns the runtime guard with the declared package.json engines requirement.
The Matrix plugin (and potentially others) requires Node >= 22.12.0,
but the runtime guard previously allowed 22.0.0+. This caused confusing
errors like 'Cannot find module @vector-im/matrix-bot-sdk' when the real
issue was an unsupported Node version.
- Update MIN_NODE from 22.0.0 to 22.12.0
- Update error message to reflect the correct version
- Update tests to use 22.12.0 as the minimum valid version
Fixes #5292
* fix: update test versions to match MIN_NODE=22.12.0
---------
Co-authored-by: Markus Glucksberg <markus@glucksberg.com>
* fix: clear stale token metrics on /new and /reset (#8929)
When starting a new session via /new or /reset, the token usage fields
(totalTokens, inputTokens, outputTokens, contextTokens) survived from the
previous session via the spread pattern in session init. This caused /status
to display misleading context usage from the old session.
Clear all four token metrics explicitly in the isNewSession block, alongside
the existing compactionCount reset. Also add diagnostic logging for session
forking via ParentSessionKey to help trace context inheritance.
* chore: apply local workspace updates (#9911)
* chore: apply local workspace updates
* fix: resolve prep findings after rebase (#9898) (thanks @gumadeiras)
* refactor: centralize model allowlist normalization (#9898) (thanks @gumadeiras)
* fix: guard model allowlist initialization (#9911)
* docs: update changelog scope for #9911
* docs: remove model names from changelog entry (#9911)
* fix: satisfy type-aware lint in model allowlist (#9911)
* fix: allow multiple compaction retries on context overflow (#8928)
Previously, overflowCompactionAttempted was a boolean flag set once, preventing
recovery when a single compaction wasn't enough. Change to a counter allowing up
to 3 attempts before giving up. Also add diagnostic logging on overflow events to
help debug early-overflow issues.
Fixes sessions that hit context overflow during long agentic turns with many tool
calls, where one compaction round isn't sufficient to bring context below limits.
* fix(errors): show clear billing error instead of cryptic API response (#8391)
* fix(errors): return clear billing error message instead of cryptic raw error (#8136)
When an LLM API provider returns a credit/billing-related error (HTTP 402,
insufficient credits, low balance, etc.), OpenClaw now shows a clear,
actionable message instead of passing through the raw/cryptic error text:
⚠️ API provider returned a billing error — your API key has run out of
credits or has an insufficient balance. Check your provider's billing
dashboard and top up or switch to a different API key.
Changes:
- formatAssistantErrorText: detect billing errors via isBillingErrorMessage()
and return a user-friendly message (placed before the generic HTTP/JSON
error fallthrough)
- sanitizeUserFacingText: same billing detection for the sanitization path
- pi-embedded-runner/run.ts: add billingFailure detection in the profile
exhaustion fallback, so the FailoverError message is billing-specific
- Added 3 new tests for credit balance, HTTP 402, and insufficient credits
* fix: extract billing error message to shared constant
* Revert "feat(skills): add QR code skill (#8817)"
This reverts commit ad13c265ba1fd22dadfe30325ed998d9a3d95e5c.
* docs: improve DM security guidance with concrete example
Add a more prominent security warning for multi-user DM setups:
- Add blockquote security warning about context leakage
- Include concrete example showing the privacy risk
- Add "When to enable this" checklist
- Clarify that default is fine for single-user setups
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs: tighten secure DM example
* docs: note secure DM guidance update (#9377) (thanks @Shrinija17)
* Agents: bump pi-mono to 0.52.5 (#9949)
* Agents: bump pi-mono to 0.52.5
* Changelog: add PR reference for pi bump
* docs: restructure Get Started tab and improve onboarding flow (#9950)
* docs: restructure Get Started tab and improve onboarding flow
- Flatten nested Onboarding group into linear First Steps flow
- Add 'What is OpenClaw?' narrative section to landing page
- Split wizard.md into streamlined overview + full reference (reference/wizard.md)
- Move Pairing to Channels > Configuration
- Move Bootstrapping to Agents > Fundamentals
- Move macOS app onboarding to Platforms > macOS companion app
- Move Lore to Help > Community
- Remove duplicate install instructions from openclaw.md
- Mirror navigation changes in zh-CN tabs
- No content deleted — all detail preserved or relocated
* docs: move deployment pages to install/, fix Platforms tab routing, clarify onboarding paths
- Move deployment guides (fly, hetzner, gcp, macos-vm, exe-dev, railway, render,
northflank) from platforms/ and root to install/
- Add 'Hosting and deployment' group to Install tab
- Slim Gateway & Ops 'Remote access and deployment' down to 'Remote access'
- Swap Platforms tab before Gateway & Ops to fix path-prefix routing
- Move macOS app onboarding into First steps (parallel to CLI wizard)
- Rename sidebar titles to 'Onboarding: CLI' / 'Onboarding: macOS App'
- Add redirects for all moved paths
- Update all internal links (en + zh-CN)
- Fix img tag syntax in onboarding.md
* fix(telegram): accept messages from group members in allowlisted groups (#9775)
* fix(telegram): accept messages from group members in allowlisted groups
Issue #4559: Telegram bot was silently dropping messages from non-paired users
in allowlisted group chats due to overly strict sender filtering.
The fix adds a check to distinguish between:
1. Group itself is allowlisted → accept messages from any member
2. Group is NOT allowlisted → only accept from allowlisted senders
Changes:
- Check if group ID is in the allowlist (or allowlist is wildcard)
- Only reject sender if they're not in allowlist AND group is not allowlisted
- Improved logging to indicate the actual reason for rejection
This preserves security controls while fixing the UX issue where group members
couldn't participate unless individually allowlisted.
Backwards compatible: existing allowlists continue to work as before.
* style: format telegram fix for oxfmt compliance
* refactor(telegram): clarify group allowlist semantics in fix for #4559
Changes:
- Rename 'isGroupInAllowlist' to 'isGroupChatIdInAllowlist' for clarity
- Expand comments to explain the semantic distinction:
* Group chat ID in allowlist -> accept any group member (fixes #4559)
* Group chat ID NOT in allowlist -> enforce sender allowlist (preserves security)
- This addresses concerns about config semantics raised in code review
The fix maintains backward compatibility:
- 'groupAllowFrom' with group chat IDs now correctly acts as group enablement
- 'groupAllowFrom' with sender IDs continues to work as sender allowlist
- Operators should use group chat IDs for group enablement, sender IDs for sender control
Note: If operators were using 'groupAllowFrom' with group IDs expecting sender-level
filtering, they should migrate to a separate sender allowlist config. This is the
intended behavior per issue #4559.
* Telegram: allow per-group groupPolicy overrides
* Telegram: support per-group groupPolicy overrides (#9775) (thanks @nicolasstanley)
---------
Co-authored-by: George Pickett <gpickett00@gmail.com>
* chore: remove tracked .DS_Store files
* Fix: Enable scrolling on the dashboard config page (#1822)
* Fix: Enable scrolling in dashboard
* Fix: Enable scrolling in dashboard
* Fix: Enable scrolling in dashboard
* feat: add xAI Grok provider support
* fix(onboard): align xAI default model to grok-4
* chore: changelog for xAI onboarding (#9885) (thanks @grp06)
* fix(cron): prevent recomputeNextRuns from skipping due jobs in onTimer (#9823)
* fix(cron): prevent recomputeNextRuns from skipping due jobs in onTimer
ensureLoaded(forceReload) called recomputeNextRuns before runDueJobs,
which recalculated nextRunAtMs to a strictly future time. Since
setTimeout always fires a few ms late, the due check (now >= nextRunAtMs)
always failed and every/cron jobs never executed. Fixes #9788.
* docs: add changelog entry for cron timer race fix (#9823) (thanks @pycckuu)
---------
Co-authored-by: Tyler Yust <TYTYYUST@YAHOO.COM>
* fix(cron): re-arm timer in finally to survive transient errors (#9948)
* fix(cron): handle legacy atMs field in schedule when computing next run (#9932)
* fix(cron): handle legacy atMs field in schedule when computing next run
The cron scheduler only checked for `schedule.at` (string) but legacy jobs
may have `schedule.atMs` (number) from before the schema migration.
This caused nextRunAtMs to stay null because:
1. Store migration runs on load but may not persist immediately
2. Race conditions or file mtime issues can skip migration
3. computeJobNextRunAtMs/computeNextRunAtMs only checked `at`, not `atMs`
Fix: Make both functions defensive by checking `atMs` first (number),
then `atMs` (string, for edge cases), then falling back to `at` (string).
This ensures jobs fire correctly even if:
- Migration hasn't run yet
- Old data was written by a previous version
- The store was manually edited
Fixes #9930
* fix: validate numeric atMs to prevent NaN/Infinity propagation
Addresses review feedback - numeric atMs values are now validated with
Number.isFinite() && atMs > 0 before use. This prevents corrupted or
manually edited stores from causing hot timer loops via setTimeout(..., NaN).
* fix(exec-approvals): coerce bare string allowlist entries to objects (#9790)
* fix(exec-approvals): coerce bare string allowlist entries (#9903) (thanks @mcaxtr)
* security: add skill/plugin code safety scanner (#9806)
* security: add skill/plugin code safety scanner module
* security: integrate skill scanner into security audit
* security: add pre-install code safety scan for plugins
* style: fix curly brace lint errors in skill-scanner.ts
* docs: add changelog entry for skill code safety scanner
* style: append ellipsis to truncated evidence strings
* fix(security): harden plugin code safety scanning
* fix: scan skills on install and report code-safety details
* fix: dedupe audit-extra import
* fix(security): make code safety scan failures observable
* fix(test): stabilize smoke + gateway timeouts (#9806) (thanks @abdelsfane)
---------
Co-authored-by: Darshil <ddhameliya@mail.sfsu.edu>
Co-authored-by: Darshil <81693876+dvrshil@users.noreply.github.com>
Co-authored-by: George Pickett <gpickett00@gmail.com>
* Thinking: accept extra-high alias and sync Codex FAQ wording
* Changelog: note #9976 thinking alias + Codex 5.3 docs sync
* fix: normalize xhigh aliases and docs sync (#9976)
* fix(agents): skip tool extraction for aborted/errored assistant messages (#4598)
Fixes tool call/tool_result pairing issues that cause permanent session corruption when assistant messages have stopReason "error" or "aborted". Includes 4 unit tests.
* fix(cron): handle undefined sessionTarget in list output (#9649) (#9752)
* fix(cron): handle undefined sessionTarget in list output (#9649)
When sessionTarget is undefined, pad() would crash with 'Cannot read
properties of undefined (reading trim)'. Use '-' as fallback value.
* test(cron): add regression test for undefined sessionTarget (#9649)
Verifies that printCronList handles jobs with undefined sessionTarget
without crashing. Test fails on main branch, passes with the fix.
* fix: use correct CronSchedule format in tests (#9752) (thanks @lailoo)
Tests were using { kind: 'at', atMs: number } but the CronSchedule type
requires { kind: 'at', at: string } where 'at' is an ISO date string.
---------
Co-authored-by: damaozi <1811866786@qq.com>
Co-authored-by: Tyler Yust <TYTYYUST@YAHOO.COM>
* chore: Update deps.
* Model: add strict gpt-5.3-codex fallback for OpenAI Codex (fixes #9989) (#9995)
* Model: allow forward-compatible OpenAI Codex GPT-5 IDs
* Model: scope Codex fallback to gpt-5.3-codex
* fix: reorder codex fallback before providerCfg, add ordering test, changelog (#9989) (thanks @w1kke)
---------
Co-authored-by: Robin <4robinlehmann@gmail.com>
* fix(nextcloud-talk): sign message text instead of JSON body (#2092)
Nextcloud Talk's ChecksumVerificationService verifies HMAC against the
extracted message/reaction text, not the full JSON body. This fixes 401
authentication errors when sending messages via the bot API.
- sendMessageNextcloudTalk: sign 'message' text only
- sendReactionNextcloudTalk: sign 'reaction' string only
* fix(slack): add mention stripPatterns for /new and /reset commands (#9971)
* fix(slack): add mention stripPatterns for /new and /reset commands
Fixes #9937
The Slack dock was missing mentions.stripPatterns that Discord has.
This caused /new and /reset to fail when sent with a mention
(e.g. @bot /reset) because <@USERID> wasn't stripped before matching.
* fix(slack): strip mentions for /new and /reset (#9971) (thanks @ironbyte-rgb)
---------
Co-authored-by: ironbyte-rgb <amontaboi76@gmail.com>
Co-authored-by: George Pickett <gpickett00@gmail.com>
* feat(feishu): replace built-in SDK with community plugin
Replace the built-in Feishu SDK with the community-maintained
clawdbot-feishu plugin by @m1heng.
Changes:
- Remove src/feishu/ directory (19 files)
- Remove src/channels/plugins/outbound/feishu.ts
- Remove src/channels/plugins/normalize/feishu.ts
- Remove src/config/types.feishu.ts
- Remove feishu exports from plugin-sdk/index.ts
- Remove FeishuConfig from types.channels.ts
New features in community plugin:
- Document tools (read/create/edit Feishu docs)
- Wiki tools (navigate/manage knowledge base)
- Drive tools (folder/file management)
- Bitable tools (read/write table records)
- Permission tools (collaborator management)
- Emoji reactions support
- Typing indicators
- Rich media support (bidirectional image/file transfer)
- @mention handling
- Skills for feishu-doc, feishu-wiki, feishu-drive, feishu-perm
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(feishu): add targeted eslint-disable comments for SDK integration
Add line-specific eslint-disable-next-line comments for SDK type casts
and union type issues, rather than file-level disables.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(feishu): fix webhook mode silent exit and receive_id_type default
- monitor.ts: throw error for webhook mode instead of silently returning,
so gateway properly marks channel as failed
- targets.ts: default receive_id_type to "user_id" instead of "open_id"
for non-prefixed IDs, fixing message delivery for enterprise user IDs
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* chore: update pnpm-lock.yaml for feishu extension deps
Add lockfile entries for:
- @larksuiteoapi/node-sdk@^1.56.1
- @sinclair/typebox@0.34.47
- zod@^4.3.6
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(feishu): sync with clawdbot-feishu #137 (multi-account support)
- Sync latest changes from clawdbot-feishu including multi-account support
- Add eslint-disable comments for SDK-related any types
- Remove unused imports
- Fix no-floating-promises in monitor.ts
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* security: redact credentials from config.get gateway responses (#9858)
* security: add skill/plugin code safety scanner module
* security: integrate skill scanner into security audit
* security: add pre-install code safety scan for plugins
* style: fix curly brace lint errors in skill-scanner.ts
* docs: add changelog entry for skill code safety scanner
* security: redact credentials from config.get gateway responses
The config.get gateway method returned the full config snapshot
including channel credentials (Discord tokens, Slack botToken/appToken,
Telegram botToken, Feishu appSecret, etc.), model provider API keys,
and gateway auth tokens in plaintext.
Any WebSocket client—including the unauthenticated Control UI when
dangerouslyDisableDeviceAuth is set—could read every secret.
This adds redactConfigSnapshot() which:
- Deep-walks the config object and masks any field whose key matches
token, password, secret, or apiKey patterns
- Uses the existing redactSensitiveText() to scrub the raw JSON5 source
- Preserves the hash for change detection
- Includes 15 test cases covering all channel types
* security: make gateway config writes return redacted values
* test: disable control UI by default in gateway server tests
* fix: redact credentials in gateway config APIs (#9858) (thanks @abdelsfane)
---------
Co-authored-by: George Pickett <gpickett00@gmail.com>
* fix: release session locks on process termination (#1962)
Adds cleanup handlers to release held file locks when the process
terminates via SIGTERM, SIGINT, or normal exit. This prevents orphaned
lock files that would block future sessions.
Fixes #1951
* fix(ollama): add streaming config and fix OLLAMA_API_KEY env var support (#9870)
* fix(ollama): add streaming config and fix OLLAMA_API_KEY env var support
Adds configurable streaming parameter to model configuration and sets streaming
to false by default for Ollama models. This addresses the corrupted response
issue caused by upstream SDK bug badlogic/pi-mono#1205 where interleaved
content/reasoning deltas in streaming responses cause garbled output.
Changes:
- Add streaming param to AgentModelEntryConfig type
- Set streaming: false default for Ollama models
- Add OLLAMA_API_KEY to envMap (was missing, preventing env var auth)
- Document streaming configuration in Ollama provider docs
- Add tests for Ollama model configuration
Users can now configure streaming per-model and Ollama authentication
via OLLAMA_API_KEY environment variable works correctly.
Fixes #8839
Related: badlogic/pi-mono#1205
* docs(ollama): use gpt-oss:20b as primary example
Updates documentation to use gpt-oss:20b as the primary example model
since it supports tool calling. The model examples now show:
- gpt-oss:20b as the primary recommended model (tool-capable)
- llama3.3 and qwen2.5-coder:32b as additional options
This provides users with a clear, working example that supports
OpenClaw's tool calling features.
* chore: remove unused vi import from ollama test
* fix: untrack dist/control-ui build artifacts (#1856)
The dist/control-ui/ files were committed before the dist/ gitignore
rule was effective. These build artifacts get regenerated during
builds, causing dirty repo errors that block the auto-update mechanism.
Removes the files from git tracking while keeping them locally and
respecting the existing dist/ gitignore entry.
Fixes #1838
Co-authored-by: Claude <noreply@anthropic.com>
* chore: add weekly upstream sync workflow
Merges openclaw/openclaw main on a weekly schedule using -X ours
so our fork patches always take priority. Opens a PR for visibility.
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Yeom-JinHo <81306489+Yeom-JinHo@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Lucas Kim <ichbinlucas211@gmail.com>
Co-authored-by: Val Alexander <68980965+BunsDev@users.noreply.github.com>
Co-authored-by: Tyler Yust <TYTYYUST@YAHOO.COM>
Co-authored-by: Christian Klotz <hello@christianklotz.co.uk>
Co-authored-by: Glucksberg <markuscontasul@gmail.com>
Co-authored-by: Ayaan Zaidi <zaidi@uplause.io>
Co-authored-by: Yudong Han <hanyd@pku.edu.cn>
Co-authored-by: Iranb <49674669+Iranb@users.noreply.github.com>
Co-authored-by: Seb Slight <sebslight@gmail.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
Co-authored-by: Shakker <shakkerdroid@gmail.com>
Co-authored-by: Josh Palmer <joshp123@users.noreply.github.com>
Co-authored-by: mudrii <mudreac@gmail.com>
Co-authored-by: Gustavo Madeira Santana <gumadeiras@gmail.com>
Co-authored-by: lsh411 <lsh411@gmail.com>
Co-authored-by: m1 16 512 <m116512@m1ui-MacBookAir-2.local>
Co-authored-by: Gustavo Madeira Santana <gumadeiras@users.noreply.github.com>
Co-authored-by: Victor Mier <victormier@gmail.com>
Co-authored-by: f-trycua <f@trycua.com>
Co-authored-by: hyf0-agent <ada.20260202@outlook.com>
Co-authored-by: hyf0-agent <hyf0-agent@users.noreply.github.com>
Co-authored-by: Kelvin Calcano <kelvinr02@hotmail.com>
Co-authored-by: M00N7682 <dfjk71@khu.ac.kr>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: damaozi <1811866786@qq.com>
Co-authored-by: cpojer <christoph.pojer@gmail.com>
Co-authored-by: sebslight <19554889+sebslight@users.noreply.github.com>
Co-authored-by: Soumyadeep Ghosh <soumyadeepghosh617@gmail.com>
Co-authored-by: Clawdbot <lukavyi@me.com>
Co-authored-by: 大猫子 <ll1042668699@gmail.com>
Co-authored-by: Rajat Joshi <78920780+18-RAJAT@users.noreply.github.com>
Co-authored-by: Michael Lee <5957298+TinyTb@users.noreply.github.com>
Co-authored-by: Slurpy <slurpy@openclaw.ai>
Co-authored-by: 九灵云 <server@jiulingyun.cn>
Co-authored-by: Tyler Yust <64381258+tyler6204@users.noreply.github.com>
Co-authored-by: Caelum <subasiarhan3@gmail.com>
Co-authored-by: MattQ <115874885+mattqdev@users.noreply.github.com>
Co-authored-by: Omar Khaleel <bmw15925@gmail.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Co-authored-by: vincentkoc <vincentkoc@users.noreply.github.com>
Co-authored-by: Glucksberg <80581902+Glucksberg@users.noreply.github.com>
Co-authored-by: Markus Glucksberg <markus@glucksberg.com>
Co-authored-by: Shrinija Kummari <shrinija@justpaid.ai>
Co-authored-by: George Pickett <gpickett00@gmail.com>
Co-authored-by: nicolasstanley <60584925+nicolasstanley@users.noreply.github.com>
Co-authored-by: Daijiro Miyazawa <dxd5001@gmail.com>
Co-authored-by: Igor Markelov <pycckuu@users.noreply.github.com>
Co-authored-by: Maksym Brashchenko <39818683+j2h4u@users.noreply.github.com>
Co-authored-by: fujiwara-tofu-shop <fujiwara@foundnone.xyz>
Co-authored-by: Marcus Castro <mcaxtr@gmail.com>
Co-authored-by: Abdel Sy Fane <32418586+abdelsfane@users.noreply.github.com>
Co-authored-by: Darshil <ddhameliya@mail.sfsu.edu>
Co-authored-by: Darshil <81693876+dvrshil@users.noreply.github.com>
Co-authored-by: slonce70 <slonce70@gmail.com>
Co-authored-by: Aisling Cahill <aisling@telnyx.com>
Co-authored-by: Robin <4robinlehmann@gmail.com>
Co-authored-by: wangai-studio <256938352+wangai-studio@users.noreply.github.com>
Co-authored-by: ironbyte-rgb <amtaboi76@gmail.com>
Co-authored-by: ironbyte-rgb <amontaboi76@gmail.com>
Co-authored-by: Yifeng Wang <xuebi@liblib.ai>
Co-authored-by: Sash Zats <sash@zats.io>
Co-authored-by: Raphael Borg Ellul Vincenti <raphael@neo-tix.com>
Co-authored-by: zerone0x <hi@trine.dev>
…or command support (#2) * fix(control-ui): resolve header logo when gateway.controlUi.basePath is set (#7178) * fix(control-ui): resolve header logo when gateway.controlUi.basePath is set * refactor(control-ui): header logo under basePath; normalize logo URL with normalizeBasePath * docs: add changelog for #7178 (thanks @Yeom-JinHo) * docs: document secure DM mode preset (#7872) * docs: document secure DM mode preset * fix: resolve merge conflict in resizable-divider * fix(security): separate untrusted channel metadata from system prompt (thanks @KonstantinMirin) * docs: update Feishu plugin docs * feat: Add Docs Chat Widget with RAG-powered Q&A (#7908) * feat: add docs chat prototype and related scripts - Introduced a minimal documentation chatbot that builds a search index from markdown files and serves responses via an API. - Added scripts for building the index and serving the chat API. - Updated package.json with new commands for chat index building and serving. - Created a new Vercel configuration file for deployment. - Added a README for the docs chat prototype detailing usage and integration. * feat: enhance docs chat with vector-based RAG pipeline - Added vector index building and serving capabilities to the docs chat. - Introduced new scripts for generating embeddings and serving the chat API using vector search. - Updated package.json with new commands for vector index operations. - Enhanced README with instructions for the new RAG pipeline and legacy keyword pipeline. - Removed outdated Vercel configuration file. * feat: enhance chat widget with markdown rendering and style updates - Integrated dynamic loading of markdown rendering for chat responses. - Implemented a fallback for markdown rendering to ensure consistent display. - Updated CSS variables for improved theming and visual consistency. - Enhanced chat bubble and input styles for better user experience. - Added new styles for markdown content in chat bubbles, including code blocks and lists. * feat: add copy buttons to chat widget for enhanced user interaction - Implemented copy buttons for chat responses and code blocks in the chat widget. - Updated CSS styles for improved visibility and interaction of copy buttons. - Adjusted textarea height for better user experience. - Enhanced functionality to allow users to easily copy text from chat bubbles and code snippets. * feat: update chat widget styles for improved user experience - Changed accent color for better visibility. - Enhanced preformatted text styles for code blocks, including padding and word wrapping. - Adjusted positioning and styles of copy buttons for chat responses and code snippets. - Improved hover effects for copy buttons to enhance interactivity. * feat: enhance chat widget styles for better responsiveness and scrollbar design - Updated chat panel dimensions for improved adaptability on various screen sizes. - Added custom scrollbar styles for better aesthetics and usability. - Adjusted chat bubble styles for enhanced visibility and interaction. - Improved layout for expanded chat widget on smaller screens. * feat: refine chat widget code block styles and copy button functionality - Adjusted padding and margin for preformatted text in chat responses for better visual consistency. - Introduced a compact style for single-line code blocks to enhance layout. - Updated copy button logic to skip short code blocks, improving user experience when copying code snippets. * feat: add resize handle functionality to chat widget for adjustable panel width - Implemented a draggable resize handle for the chat widget's sidebar, allowing users to adjust the panel width. - Added CSS styles for the resize handle, including hover effects and responsive behavior. - Integrated drag-to-resize logic to maintain user-set width across interactions. - Ensured the panel resets to default width when closed, enhancing user experience. * feat: implement rate limiting and error handling in chat API - Added rate limiting functionality to the chat API, allowing a maximum number of requests per IP within a specified time window. - Implemented error handling for rate limit exceeded responses, including appropriate headers and retry instructions. - Enhanced error handling for other API errors, providing user-friendly messages for various failure scenarios. - Updated README to include new environment variables for rate limiting configuration. * feat: integrate Upstash Vector for enhanced document retrieval in chat API - Implemented Upstash Vector as a cloud-based storage solution for document chunks, replacing the local LanceDB option. - Added auto-detection of storage mode based on environment variables for seamless integration. - Updated the chat API to utilize the new retrieval mechanism, enhancing response accuracy and performance. - Enhanced README with setup instructions for Upstash and updated environment variable requirements. - Introduced new scripts and configurations for managing the vector index and API interactions. * feat: add create-markdown-preview.js for markdown rendering - Introduced a new script for framework-agnostic HTML rendering of markdown content. - The script includes various parsing functions to handle different markdown elements. - Updated the chat widget to load the vendored version of @create-markdown/preview for improved markdown rendering. * docs: update README for Upstash Vector index setup and environment variables - Enhanced instructions for creating a Vector index in Upstash, including detailed settings and important notes. - Clarified environment variable requirements for both Upstash and LanceDB modes. - Improved formatting and organization of setup steps for better readability. - Added health check and API endpoint details for clearer usage guidance. * feat: add TRUST_PROXY environment variable for IP address handling - Introduced the TRUST_PROXY variable to control the trust of X-Forwarded-For headers when behind a reverse proxy. - Updated the README to document the new environment variable and its default value. - Enhanced the getClientIP function to conditionally trust proxy headers based on the TRUST_PROXY setting. * feat: add ALLOWED_ORIGINS environment variable for CORS configuration - Introduced the ALLOWED_ORIGINS variable to specify allowed origins for CORS, enhancing security and flexibility. - Updated the README to document the new environment variable and its usage. - Refactored CORS handling in the server code to utilize the ALLOWED_ORIGINS setting for dynamic origin control. * fix: ensure complete markdown rendering in chat widget - Added logic to flush any remaining buffered bytes from the decoder, ensuring that all text is rendered correctly in the assistant bubble. - Updated the assistant bubble's innerHTML to reflect the complete markdown content after streaming completes. * feat: enhance DocsStore with improved vector handling and similarity conversion - Added a constant for the distance metric used in vector searches, clarifying the assumption of L2 distance. - Updated the createTable method to ensure all chunk properties are correctly mapped during table creation. - Improved the similarity score calculation by providing a clear explanation of the conversion from L2 distance, ensuring accurate ranking of results. * chore: fix code formatting * Revert "chore: fix code formatting" This reverts commit 6721f5b0b7bf60b76c519ccadfa41742f19ecf87. * chore: format code for improved readability - Reformatted code in serve.ts to enhance readability by adjusting indentation and line breaks. - Ensured consistent style for function return types and object properties throughout the file. * feat: Update API URL selection logic in chat widget - Enhanced the API URL configuration to prioritize explicit settings, defaulting to localhost for development and using a production URL otherwise. - Improved clarity in the code by adding comments to explain the logic behind the API URL selection. * chore: Update documentation structure for improved organization - Changed the path for the "Start Here" page to "start/index" for better clarity. - Reformatted the "Web & Interfaces" and "Help" groups to use multi-line arrays for improved readability. * feat: Enhance markdown preview integration and improve chat widget asset loading - Wrapped the markdown preview functionality in an IIFE to expose a global API for easier integration. - Updated the chat widget to load the markdown preview library dynamically, checking for existing instances to avoid duplicate loads. - Adjusted asset paths in the chat widget to ensure correct loading based on the environment (local or production). - Added CORS headers in the Vercel configuration for improved API accessibility. * fix: Update chat API URL to include '/api' for correct endpoint access - Modified the chat configuration and widget files to append '/api' to the API URL, ensuring proper endpoint usage in production and local environments. * refactor: Simplify docs-chat configuration and remove unused scripts - Removed outdated scripts and configurations related to the docs-chat feature, including build and serve scripts, as well as the associated package.json and README files. - Streamlined the API URL configuration in the chat widget for better clarity and maintainability. - Updated the package.json to remove unnecessary scripts related to the now-deleted functionality. * refactor: Update documentation structure for improved clarity - Changed the path for the "Start Here" page from "start/index" to "index" to enhance navigation and organization within the documentation. * chore: Remove unused dependencies from package.json and pnpm-lock.yaml - Deleted `@lancedb/lancedb`, `@upstash/vector`, and `openai` from both package.json and pnpm-lock.yaml to streamline the project and reduce bloat. * chore: Clean up .gitignore by removing obsolete entries - Deleted unused entries related to the docs-chat vector database from .gitignore to maintain a cleaner configuration. * chore: Remove deprecated chat configuration and markdown preview script - Deleted the `create-markdown-preview.js` script and the `docs-chat-config.js` file to eliminate unused assets and streamline the project. - Updated the `docs-chat-widget.js` to directly reference the markdown library from a CDN, enhancing maintainability. * chore: Update markdown rendering in chat widget to use marked library - Replaced the deprecated `create-markdown-preview` library with the `marked` library for markdown rendering. - Adjusted the script loading mechanism to fetch `marked` from a CDN, improving performance and maintainability. - Enhanced the markdown rendering function to ensure security by disabling HTML pass-through and opening links in new tabs. * Delete docs/start/index.md * fix: harden voice-call webhook verification * fix(cron): fix timeout, add timestamp validation, enable file sync Fixes #7667 Task 1: Fix cron operation timeouts - Increase default gateway tool timeout from 10s to 30s - Increase cron-specific tool timeout to 60s - Increase CLI default timeout from 10s to 30s - Prevents timeouts when gateway is busy with long-running jobs Task 2: Add timestamp validation - New validateScheduleTimestamp() function in validate-timestamp.ts - Rejects atMs timestamps more than 1 minute in the past - Rejects atMs timestamps more than 10 years in the future - Applied to both cron.add and cron.update operations - Provides helpful error messages with current time and offset Task 3: Enable file sync for manual edits - Track file modification time (storeFileMtimeMs) in CronServiceState - Check file mtime in ensureLoaded() and reload if changed - Recompute next runs after reload to maintain accuracy - Update mtime after persist() to prevent reload loop - Dashboard now picks up manual edits to ~/.openclaw/cron/jobs.json * feat(cron): introduce delivery modes for isolated jobs - Added support for new delivery modes in cron jobs: `announce`, `deliver`, and `none`. - Updated documentation to reflect changes in delivery options and usage examples. - Enhanced the cron job schema to include delivery configuration. - Refactored related CLI commands and UI components to accommodate the new delivery settings. - Improved handling of legacy delivery fields for backward compatibility. This update allows users to choose how output from isolated jobs is delivered, enhancing flexibility in job management. * feat(cron): default isolated jobs to announce delivery and enhance scheduling options - Updated isolated cron jobs to default to `announce` delivery mode, improving user experience. - Enhanced scheduling options to accept ISO 8601 timestamps for `schedule.at`, while still supporting epoch milliseconds. - Refined documentation to clarify delivery modes and scheduling formats. - Adjusted related CLI commands and UI components to reflect these changes, ensuring consistency across the platform. - Improved handling of legacy delivery fields for backward compatibility. This update streamlines the configuration of isolated jobs, making it easier for users to manage job outputs and schedules. * feat(cron): enhance one-shot job behavior and CLI options - Default one-shot jobs to delete after success, improving job management. - Introduced `--keep-after-run` CLI option to allow users to retain one-shot jobs post-execution. - Updated documentation to clarify default behaviors and new options for one-shot jobs. - Adjusted cron job creation logic to ensure consistent handling of delete options. - Enhanced tests to validate new behaviors and ensure reliability. This update streamlines the handling of one-shot jobs, providing users with more control over job persistence and execution outcomes. * feat(cron): enhance delivery modes and job configuration - Updated isolated cron jobs to support new delivery modes: `announce` and `none`, improving output management. - Refactored job configuration to remove legacy fields and streamline delivery settings. - Enhanced the `CronJobEditor` UI to reflect changes in delivery options, including a new segmented control for delivery mode selection. - Updated documentation to clarify the new delivery configurations and their implications for job execution. - Improved tests to validate the new delivery behavior and ensure backward compatibility with legacy settings. This update provides users with greater flexibility in managing how isolated jobs deliver their outputs, enhancing overall usability and clarity in job configurations. * feat(cron): set default enabled state for cron jobs - Added logic to default the `enabled` property to `true` if not explicitly set as a boolean in the cron job input. - Updated job creation and store functions to ensure consistent handling of the `enabled` state across the application. - Enhanced input normalization to improve job configuration reliability. This update ensures that cron jobs are enabled by default, enhancing user experience and reducing potential misconfigurations. * refactor(cron): update delivery instructions for isolated agent - Revised the delivery instructions in the isolated agent's command body to clarify that summaries should be returned as plain text and will be delivered by the main agent. - Removed the previous directive regarding messaging tools to streamline communication guidelines. This change enhances clarity in the delivery process for isolated agent tasks. * feat(cron): enhance delivery handling and testing for isolated jobs - Introduced new properties for explicit message targeting and message tool disabling in the EmbeddedRunAttemptParams type. - Updated cron job tests to validate best-effort delivery behavior and handling of delivery failures. - Added logic to clear delivery settings when switching session targets in cron jobs. - Improved the resolution of delivery failures and best-effort logic in the isolated agent's run function. This update enhances the flexibility and reliability of delivery mechanisms in isolated cron jobs, ensuring better handling of message delivery scenarios. * refactor(cron): improve delivery configuration handling in CronJobEditor and CLI - Enhanced the delivery configuration logic in CronJobEditor to explicitly set the bestEffort property based on job settings. - Refactored the CLI command to streamline delivery object creation, ensuring proper handling of optional fields like channel and to. - Improved code readability and maintainability by restructuring delivery assignment logic. This update clarifies the delivery configuration process, enhancing the reliability of job settings in both the editor and CLI. * feat(cron): enhance legacy delivery handling in job patches - Introduced logic to map legacy payload delivery updates onto the delivery object for `agentTurn` jobs, ensuring backward compatibility with legacy clients. - Added tests to validate the correct application of legacy delivery settings in job patches, improving reliability in job configuration. - Refactored delivery handling functions to streamline the merging of legacy delivery fields into the current job structure. This update enhances the flexibility of delivery configurations, ensuring that legacy settings are properly handled in the context of new job patches. * fix(cron): fix test failures and regenerate protocol files - Add forceReload option to ensureLoaded to avoid stat I/O in normal paths while still detecting cross-service writes in the timer path - Post isolated job summary back to main session (restores the old isolation.postToMainPrefix behavior via delivery model) - Update legacy migration tests to check delivery.channel instead of payload.channel (normalization now moves delivery fields to top-level) - Remove legacy deliver/channel/to/bestEffortDeliver from payload schema - Update protocol conformance test for delivery modes - Regenerate GatewayModels.swift (isolation -> delivery) * UI: handle future timestamps in formatAgo * Changelog: move cron entries to 2026.2.3 * fix: cron announce delivery path (#8540) (thanks @tyler6204) * Telegram: use Grammy types directly, add typed Probe/Audit to plugin interface (#8403) * Telegram: replace duplicated types with Grammy imports, add Probe/Audit generics to plugin interface * Telegram: remove legacy forward metadata (deprecated in Bot API 7.0), simplify required-field checks * Telegram: clean up remaining legacy references and unnecessary casts * Telegram: keep RequestInit parameter type in proxy fetch (addresses review feedback) * Telegram: add exhaustiveness guard to resolveForwardOrigin switch * fix(telegram): include forward_from_chat metadata in forwarded message context (#8133) Extract missing metadata from forwarded Telegram messages: - Add fromChatType to TelegramForwardedContext, capturing the original chat type (channel/supergroup/group) from forward_from_chat.type and forward_origin.chat/sender_chat.type - Add fromMessageId to capture the original message ID from channel forwards - Read author_signature from forward_origin objects (modern API), preferring it over the deprecated forward_signature field - Pass ForwardedFromChatType and ForwardedFromMessageId through to the inbound context payload - Add test coverage for forward_origin channel/chat types, including author_signature extraction and fromChatType propagation * fix: trim legacy signature fallback, type fromChatType as union * fix: telegram forward metadata + cron delivery guard (#8392) (thanks @Glucksberg) * fix(imessage): unify timeout configuration with configurable probeTimeoutMs - Add probeTimeoutMs config option to channels.imessage - Export DEFAULT_IMESSAGE_PROBE_TIMEOUT_MS constant (10s) from probe.ts - Propagate timeout config through all iMessage probe/RPC operations - Fix hardcoded 2000ms timeouts that were too short for SSH connections Closes: timeout issues when using SSH wrapper scripts (imsg-ssh) * fix: address review comments - Use optional timeoutMs parameter (undefined = use config/default) - Extract DEFAULT_IMESSAGE_PROBE_TIMEOUT_MS to shared constants.ts - Import constant in client.ts instead of hardcoding - Re-export constant from probe.ts for backwards compatibility * fix(imessage): detect self-chat echoes to prevent infinite loops (#8680) * fix: align proxy fetch typing * feat: add cloudflare ai gateway provider * fix: force reload cron store * Revert "feat: Add Docs Chat Widget with RAG-powered Q&A (#7908)" (#8834) This reverts commit fa4b28d7af7464b07271bfef6c028e4135548f44. * fix(web ui): agent model selection * Docs: landing page revamp (#8885) * Docs: refresh landing page * Docs: add landing page companion pages * Docs: drop legacy Jekyll assets * Docs: remove legacy terminal css test * Docs: restore terminal css assets * Docs: remove terminal css assets * fix(app-render): handle optional model in renderApp function * chore: replace landpr prompt with end-to-end landing workflow (#8916) * 🤖 docs: mirror landing revamp for zh-CN What: - add zh-CN versions of landing revamp pages (features, quickstart, docs directory, network model, credits) - refresh zh-CN index and hubs, plus glossary entries Why: - keep Chinese docs aligned with the new English landing experience - ensure navigation surfaces the new entry points Tests: - pnpm build && pnpm check && pnpm test * 🤖 docs: note zh-CN landing revamp (#8994) (thanks @joshp123) What: - add changelog entry for the zh-CN landing revamp docs Why: - record the doc update and thank the contributor Tests: - pnpm lint && pnpm build && pnpm test * feat: add shell completion installation prompt to CLI update command * feat: add shell completion test script for installation verification * completion: export cache utilities and require cached file for installation - Export `resolveCompletionCachePath` and `completionCacheExists` for external use - Update `installCompletion` to require cache existence (never use slow dynamic pattern) - Add `usesSlowDynamicCompletion` to detect old `source <(...)` patterns - Add `getShellProfilePath` helper for consistent profile path resolution - Update `formatCompletionSourceLine` to always use cached file * doctor: add shell completion check module - Add `checkShellCompletionStatus` to get profile/cache/slow-pattern status - Add `ensureCompletionCacheExists` for silent cache regeneration - Add `doctorShellCompletion` to check and fix completion issues: - Auto-upgrade old slow dynamic patterns to cached version - Auto-regenerate cache if profile exists but cache is missing - Prompt to install if no completion is configured * doctor: integrate shell completion check into doctor command - Import and call `doctorShellCompletion` during doctor run - Checks/fixes completion issues before gateway health check * update: use shared completion helpers for shell completion setup - Replace inline completion logic with `checkShellCompletionStatus` and `ensureCompletionCacheExists` - Auto-upgrade old slow dynamic patterns silently during update - Auto-regenerate cache if profile exists but cache is missing - Prompt to install if no completion is configured * onboard: use shared completion helpers for shell completion setup - Replace inline completion logic with `checkShellCompletionStatus` and `ensureCompletionCacheExists` - Auto-upgrade old slow dynamic patterns silently during onboarding - Auto-regenerate cache if profile exists but cache is missing - Prompt to install if no completion is configured * scripts: update test-shell-completion to use shared helpers - Use `checkShellCompletionStatus` and `ensureCompletionCacheExists` from doctor-completion - Display "Uses slow pattern" status in output - Simulate doctor/update/onboard behavior for all completion scenarios - Remove duplicated utility functions * changelog: add shell completion auto-fix entry * feat: per-channel responsePrefix override (#9001) * feat: per-channel responsePrefix override Add responsePrefix field to all channel config types and Zod schemas, enabling per-channel and per-account outbound response prefix overrides. Resolution cascade (most specific wins): L1: channels.<ch>.accounts.<id>.responsePrefix L2: channels.<ch>.responsePrefix L3: (reserved for channels.defaults) L4: messages.responsePrefix (existing global) Semantics: - undefined -> inherit from parent level - empty string -> explicitly no prefix (stops cascade) - "auto" -> derive [identity.name] from routed agent Changes: - Core logic: resolveResponsePrefix() in identity.ts accepts optional channel/accountId and walks the cascade - resolveEffectiveMessagesConfig() passes channel context through - Types: responsePrefix added to WhatsApp, Telegram, Discord, Slack, Signal, iMessage, Google Chat, MS Teams, Feishu, BlueBubbles configs - Zod schemas: responsePrefix added for config validation - All channel handlers wired: telegram, discord, slack, signal, imessage, line, heartbeat runner, route-reply, native commands - 23 new tests covering backward compat, channel/account levels, full cascade, auto keyword, empty string stops, unknown fallthrough Fully backward compatible - no existing config is affected. Fixes #8857 * fix: address CI lint + review feedback - Replace Record<string, any> with proper typed helpers (no-explicit-any) - Add curly braces to single-line if returns (eslint curly) - Fix JSDoc: 'Per-channel' → 'channel/account' on shared config types - Extract getChannelConfig() helper for type-safe dynamic key access * fix: finish responsePrefix overrides (#9001) (thanks @mudrii) * fix: normalize prefix wiring and types (#9001) (thanks @mudrii) --------- Co-authored-by: Gustavo Madeira Santana <gumadeiras@gmail.com> * Discord: allow disabling thread starter context * feat(heartbeat): add accountId config option for multi-agent routing (#8702) * feat(heartbeat): add accountId config option for multi-agent routing Add optional accountId field to heartbeat configuration, allowing multi-agent setups to explicitly specify which Telegram account should be used for heartbeat delivery. Previously, heartbeat delivery would use the accountId from the session's deliveryContext. When a session had no prior conversation history, heartbeats would default to the first/primary account instead of the agent's intended bot. Changes: - Add accountId to HeartbeatSchema (zod-schema.agent-runtime.ts) - Use heartbeat.accountId with fallback to session accountId (targets.ts) Backward compatible: if accountId is not specified, behavior is unchanged. Closes #8695 * fix: improve heartbeat accountId routing (#8702) (thanks @lsh411) * fix: harden heartbeat accountId routing (#8702) (thanks @lsh411) * fix: expose heartbeat accountId in status (#8702) (thanks @lsh411) * chore: format status + heartbeat tests (#8702) (thanks @lsh411) --------- Co-authored-by: m1 16 512 <m116512@m1ui-MacBookAir-2.local> Co-authored-by: Gustavo Madeira Santana <gumadeiras@gmail.com> * TUI/Gateway: fix pi streaming + tool routing + model display + msg updating (#8432) * TUI/Gateway: fix pi streaming + tool routing * Tests: clarify verbose tool output expectation * fix: avoid seq gaps for targeted tool events (#8432) (thanks @gumadeiras) * Telegram: remove @ts-nocheck from bot.ts, fix duplicate error handler, harden sticker caching (#9077) * Telegram: remove @ts-nocheck from bot.ts and bot-message-dispatch.ts - bot/types.ts: TelegramContext.me uses UserFromGetMe (Grammy) instead of manual inline type - bot.ts: remove 6 unsafe casts (as any, as unknown, as object), use Grammy types directly - bot.ts: remove dead message_thread_id access on reactions (not in Telegram Bot API) - bot.ts: remove resolveThreadSessionKeys import (no longer needed for reactions) - bot-message-dispatch.ts: replace ': any' with DispatchTelegramMessageParams type - bot-message-dispatch.ts: add sticker.fileId guard before cache access - bot.test.ts: update reaction tests, remove dead DM thread-reaction test * Telegram: remove duplicate bot.catch handler (only the last one runs in Grammy) * Telegram: remove @ts-nocheck from bot.ts, fix duplicate error handler, harden sticker caching (#9077) * Security: Prevent gateway credential exfiltration via URL override (#9179) * Gateway: require explicit auth for url overrides * Gateway: scope credential blocking to non-local URLs only Address review feedback: the previous fix blocked credential fallback for ALL URL overrides, which was overly strict and could break workflows that use --url to switch between loopback/tailnet without passing credentials. Now credential fallback is only blocked for non-local URLs (public IPs, external hostnames). Local addresses (127.0.0.1, localhost, private IPs like 192.168.x.x, 10.x.x.x, tailnet 100.x.x.x) still get credential fallback as before. This maintains the security fix (preventing credential exfiltration to attacker-controlled URLs) while preserving backward compatibility for legitimate local URL overrides. * Security: require explicit credentials for gateway url overrides (#8113) (thanks @victormier) * Gateway: reuse explicit auth helper for url overrides (#8113) (thanks @victormier) * Tests: format gateway chat test (#8113) (thanks @victormier) * Tests: require explicit auth for gateway url overrides (#8113) (thanks @victormier) --------- Co-authored-by: Victor Mier <victormier@gmail.com> * Tests: restore TUI gateway env * Security: harden sandboxed media handling (#9182) * Message: enforce sandbox for media param * fix: harden sandboxed media handling (#8780) (thanks @victormier) * chore: format message action runner (#8780) (thanks @victormier) --------- Co-authored-by: Victor Mier <victormier@gmail.com> * Telegram: remove @ts-nocheck from bot-message.ts (#9180) * Telegram: remove @ts-nocheck from bot-message.ts, type deps via Omit<BuildTelegramMessageContextParams> * Telegram: widen allMedia to TelegramMediaRef[] so stickerMetadata flows through * Telegram: remove @ts-nocheck from bot-message.ts (#9180) * fix: cover anonymous voice allowlist callers (#8104) (thanks @victormier) (#9188) * Security: owner-only tools + command auth hardening (#9202) * Security: gate whatsapp_login by sender auth * Security: treat undefined senderAuthorized as unauthorized (opt-in) * fix: gate whatsapp_login to owner senders (#8768) (thanks @victormier) * fix: add explicit owner allowlist for tools (#8768) (thanks @victormier) * fix: normalize escaped newlines in send actions (#8768) (thanks @victormier) --------- Co-authored-by: Victor Mier <victormier@gmail.com> * Telegram: remove last @ts-nocheck from bot-handlers.ts (#9206) * Telegram: remove @ts-nocheck from bot-handlers.ts, use Grammy types directly, deduplicate StickerMetadata * Telegram: remove last @ts-nocheck from bot-handlers.ts (#9206) * Message: clarify media schema + fix MEDIA newline * fix: enforce owner allowlist for commands * fix: infer --auth-choice from API key flags during non-interactive onboarding (#9241) * fix: infer --auth-choice from API key flags during non-interactive onboarding When --anthropic-api-key (or other provider key flags) is passed without an explicit --auth-choice, the auth choice defaults to "skip", silently discarding the API key. This means the gateway starts without credentials and fails on every inbound message with "No API key found for provider". Add inferAuthChoiceFromFlags() to derive the correct auth choice from whichever provider API key flag was supplied, so credentials are persisted to auth-profiles.json as expected. Fixes #8481 * fix: infer auth choice from API key flags (#8484) (thanks @f-trycua) * refactor: centralize auth choice inference flags (#8484) (thanks @f-trycua) --------- Co-authored-by: f-trycua <f@trycua.com> * chore: sync plugin versions to 2026.2.3 * fix(mac): resolve cron schedule formatters * chore(mac): update appcast for 2026.2.3 * chore: update 2026.2.3 notes * fix: gracefully downgrade xhigh thinking level in cron isolated agent (#9363) When thinkingDefault is set to "xhigh" but the configured model does not support it (e.g. Claude), the cron isolated-agent path throws a hard error causing the job to fail. The interactive chat path already handles this by silently downgrading to "high". Apply the same graceful downgrade in the cron path: log a warning and fall back to "high" instead of crashing. Co-authored-by: hyf0-agent <hyf0-agent@users.noreply.github.com> * fix: restore discord owner hint from allowlists * fix: remove unused cron import * fix(cli): resolve bundled chrome extension path * test(cli): use unique temp dir for extension install * fix(cli): support bundled extension path in dist root * style(cli): satisfy lint rules in extension path resolver * fix: resolve bundled chrome extension assets (#8914) (thanks @kelvinCB) * Tests: add test coverage for security/windows-acl.ts Adds comprehensive unit tests for Windows ACL inspection utilities: - resolveWindowsUserPrincipal: username resolution with fallback - parseIcaclsOutput: icacls output parsing - summarizeWindowsAcl: ACL entry classification (trusted/world/group) - inspectWindowsAcl: async ACL inspection with mocked exec - formatWindowsAclSummary: summary string formatting - formatIcaclsResetCommand: reset command string generation - createIcaclsResetCommand: structured reset command generation All 26 tests passing. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: stabilize windows acl tests and command auth registry (#9335) (thanks @M00N7682) * test: register discord plugin in allowlist test * chore: bump version to 2026.2.4 * fix: resolve discord owner allowFrom matches * fix(telegram): preserve DM topic threadId in deliveryContext When receiving messages in Telegram DM topics (Topics in Private Chats), the threadId was not saved in the session's deliveryContext, causing replies to go to General chat instead of the topic. Now we pass threadId to updateLastRoute for DM topics. Fixes #8891 * test(telegram): add DM topic threadId deliveryContext test for #8891 Verifies that threadId is passed to updateLastRoute for DM topics. Test fails on main branch, passes with the fix. * fix: preserve telegram DM topic threadId (#9039) (thanks @lailoo) * Update deps. * chore: Typecheck test helper files. * Docs: streamline start and install docs (#9648) * docs(start): streamline getting started flow * docs(nav): reorganize start and install sections * docs(style): move custom css to style.css * docs(navigation): align zh-CN ordering * docs(navigation): localize zh-Hans labels * docs(install): rename install overview page * CLI: sort commands alphabetically in help output Fixes #7964 Added sortSubcommands: true to configureHelp() to display commands in alphabetical order when running 'openclaw --help'. * fix: update changelog for help sorting (#8068) (thanks @deepsoumya617) * docs(onboarding): add bootstrapping page (#9767) * docs: fix onboarding rendering issues * chore: reset appcast to 2026.2.3 * fix(telegram): pass parentPeer for forum topic binding inheritance (#9789) Fixes #9545 and #9351. When a message comes from a Telegram forum topic, the peer ID includes the topic suffix (e.g., `-1001234567890:topic:99`). Users configure bindings with the base group ID, which previously did not match. This adds `parentPeer` to `resolveAgentRoute()` calls for forum groups, enabling binding inheritance from the parent group to all topics. - Extract `buildTelegramParentPeer()` helper in bot/helpers.ts - Pass parentPeer in bot-message-context.ts, bot-handlers.ts, bot-native-commands.ts, and bot.ts (reaction handler) - Add tests for forum topic routing and topic precedence * docs(onboarding): streamline CLI onboarding docs (#9830) * fix: auto-inject Telegram forum topic threadId in message tool When using Telegram DM topics (forum topics), messages sent via the message tool (media, buttons, etc.) land in General Topic instead of the user's current topic. This happens because Slack has resolveSlackAutoThreadId for auto-threading but Telegram had no equivalent. Add resolveTelegramAutoThreadId that mirrors the Slack pattern: - When channel is telegram and no explicit threadId is provided - Check if toolContext.currentThreadTs (the topic ID) is set - Verify the target matches the originating chat - Inject the threadId into params so the Telegram plugin action handler picks it up for sendMessage/sendMedia The subagent announce path already correctly passes threadId via requesterOrigin (set from agentThreadId in sessions-spawn-tool), so no changes needed there. * test: cover telegram topic threadId auto-injection and subagent origin threading * fix: pass threadId/to/accountId from parent to subagent gateway call When spawning a subagent, the requesterOrigin's threadId, to, and accountId were not forwarded to the callGateway({method:'agent'}) params. This meant the subagent's runContext had no currentThreadTs or currentChannelId, so resolveTelegramAutoThreadId could not auto-inject the forum topic thread ID when the subagent used the message tool. Changes: - sessions-spawn-tool: pass to, accountId, threadId from requesterOrigin - run-context: populate currentChannelId from opts.to as fallback Fixes subagent messages landing in General Topic instead of the correct Telegram DM topic thread. * fix: telegram topic auto-threading — use parseTelegramTarget, add tests (#7235) (thanks @Lukavyi) * update handle * docs: fix incorrect model.fallback to model.fallbacks in Ollama config (#9384) (#9749) Both English and Chinese documentation had incorrect configuration template using 'fallback' instead of 'fallbacks' in agents.defaults.model config. Co-authored-by: damaozi <1811866786@qq.com> * fix(cli): avoid NODE_OPTIONS for --disable-warning (#9691) (thanks @18-RAJAT) Fixes npm pack failing on modern Node where --disable-warning is disallowed in NODE_OPTIONS. * feat: add Claude Opus 4.6 to built-in model catalog (#9853) * feat: add Claude Opus 4.6 to built-in model catalog - Update default model from claude-opus-4-5 to claude-opus-4-6 - Add opus-4.6 model ID normalization - Add claude-opus-4-6 to live model filter prefixes - Update image tool to prefer claude-opus-4-6 for vision - Add CLI backend alias for opus-4.6 - Update onboard auth default selections to include opus-4.6 - Update model picker placeholder Closes #9811 * test: update tests for claude-opus-4-6 default - Fix model-alias-defaults test to use claude-opus-4-6 - Fix image-tool test to expect claude-opus-4-6 in fallbacks * feat: support claude-opus-4-6 * docs: update changelog for opus 4.6 (#9853) (thanks @TinyTb) * chore: bump pi to 0.52.0 --------- Co-authored-by: Slurpy <slurpy@openclaw.ai> Co-authored-by: Peter Steinberger <steipete@gmail.com> * 🤖 Feishu: expand channel support What: - add post parsing, doc link extraction, routing, replies, reactions, typing, and user lookup - fix media download/send flows and make doc fetches domain-aware - update Feishu docs and clawtributor credits Why: - raise Feishu parity with other channels and avoid dropped group messages - keep replies threaded while supporting Lark domains - document new configuration and credit the contributor Tests: - pnpm build - pnpm check - pnpm test (gateway suite timed out; reran pnpm vitest run --config vitest.gateway.config.ts) Co-authored-by: 九灵云 <server@jiulingyun.cn> * 🤖 Feishu: tighten mention gating What: - require the bot open_id match for group mention detection when available Why: - prevent replies when other users are mentioned and the bot id is known Tests: - pnpm test * fix: remove orphaned tool_results during compaction pruning When pruneHistoryForContextShare drops chunks of messages, it could drop an assistant message with tool_use blocks while leaving corresponding tool_result messages in the kept portion. These orphaned tool_results cause Anthropic's API to reject the session with 'unexpected tool_use_id'. Fix by calling repairToolUseResultPairing after each chunk drop to clean up any orphaned tool_results. This reuses existing battle-tested code from session-transcript-repair.ts. Fixes #9769, #9724, #9672 * fix cron scheduling and reminder delivery regressions (#9733) * fix(cron): prevent timer from allowing process exit (fixes #9694) The cron timer was using .unref(), which caused the Node.js event loop to exit or sleep if no other handles were active. This prevented cron jobs from firing in some environments. * fix(cron): infer delivery target for isolated jobs (fixes #9683) When creating isolated agentTurn jobs (e.g. reminders) without explicit delivery options, the job would default to 'announce' but fail to resolve the target conversation. Now, we infer the channel and recipient from the agent's current session key. * fix(cron): enhance delivery inference for threaded sessions and null inputs (#9733) Improves the delivery inference logic in the cron tool to correctly handle threaded session keys and cases where delivery is explicitly set to null. This ensures that the appropriate delivery mode and target are inferred based on the agent's session key, enhancing the reliability of job execution. * fix: preserve telegram topic delivery inference (#9733) (thanks @tyler6204) * fix: simplify cron delivery merge spread (#9733) (thanks @tyler6204) * chore: add agent credentials to gitignore (#9874) Protect sensitive files from accidental commit: - memory/ (moltbook credentials, session data) - .agent/*.json (agent config, moltbook.json) Workflows in .agent/workflows/ remain tracked. Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> * Docs: escape hash symbol in help channel names in issue template (#9695) * feat(skills): add QR code skill (#8817) feat(skills): add QR code generation and reading skill Adds qr-code skill with: - qr_generate.py - Generate QR codes with customizable size/error correction - qr_read.py - Decode QR codes from images - SKILL.md documentation Co-authored-by: Omar-Khaleel * chore(agentsmd): add tsgo command to AGENTS.md (#9894) Add `pnpm tsgo` command to AGENTS.md development reference Co-authored-by: vincentkoc <vincentkoc@users.noreply.github.com> * fix(runtime): bump minimum Node.js version to 22.12.0 (#5370) * fix(runtime): bump minimum Node.js version to 22.12.0 Aligns the runtime guard with the declared package.json engines requirement. The Matrix plugin (and potentially others) requires Node >= 22.12.0, but the runtime guard previously allowed 22.0.0+. This caused confusing errors like 'Cannot find module @vector-im/matrix-bot-sdk' when the real issue was an unsupported Node version. - Update MIN_NODE from 22.0.0 to 22.12.0 - Update error message to reflect the correct version - Update tests to use 22.12.0 as the minimum valid version Fixes #5292 * fix: update test versions to match MIN_NODE=22.12.0 --------- Co-authored-by: Markus Glucksberg <markus@glucksberg.com> * fix: clear stale token metrics on /new and /reset (#8929) When starting a new session via /new or /reset, the token usage fields (totalTokens, inputTokens, outputTokens, contextTokens) survived from the previous session via the spread pattern in session init. This caused /status to display misleading context usage from the old session. Clear all four token metrics explicitly in the isNewSession block, alongside the existing compactionCount reset. Also add diagnostic logging for session forking via ParentSessionKey to help trace context inheritance. * chore: apply local workspace updates (#9911) * chore: apply local workspace updates * fix: resolve prep findings after rebase (#9898) (thanks @gumadeiras) * refactor: centralize model allowlist normalization (#9898) (thanks @gumadeiras) * fix: guard model allowlist initialization (#9911) * docs: update changelog scope for #9911 * docs: remove model names from changelog entry (#9911) * fix: satisfy type-aware lint in model allowlist (#9911) * fix: allow multiple compaction retries on context overflow (#8928) Previously, overflowCompactionAttempted was a boolean flag set once, preventing recovery when a single compaction wasn't enough. Change to a counter allowing up to 3 attempts before giving up. Also add diagnostic logging on overflow events to help debug early-overflow issues. Fixes sessions that hit context overflow during long agentic turns with many tool calls, where one compaction round isn't sufficient to bring context below limits. * fix(errors): show clear billing error instead of cryptic API response (#8391) * fix(errors): return clear billing error message instead of cryptic raw error (#8136) When an LLM API provider returns a credit/billing-related error (HTTP 402, insufficient credits, low balance, etc.), OpenClaw now shows a clear, actionable message instead of passing through the raw/cryptic error text: ⚠️ API provider returned a billing error — your API key has run out of credits or has an insufficient balance. Check your provider's billing dashboard and top up or switch to a different API key. Changes: - formatAssistantErrorText: detect billing errors via isBillingErrorMessage() and return a user-friendly message (placed before the generic HTTP/JSON error fallthrough) - sanitizeUserFacingText: same billing detection for the sanitization path - pi-embedded-runner/run.ts: add billingFailure detection in the profile exhaustion fallback, so the FailoverError message is billing-specific - Added 3 new tests for credit balance, HTTP 402, and insufficient credits * fix: extract billing error message to shared constant * Revert "feat(skills): add QR code skill (#8817)" This reverts commit ad13c265ba1fd22dadfe30325ed998d9a3d95e5c. * docs: improve DM security guidance with concrete example Add a more prominent security warning for multi-user DM setups: - Add blockquote security warning about context leakage - Include concrete example showing the privacy risk - Add "When to enable this" checklist - Clarify that default is fine for single-user setups Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * docs: tighten secure DM example * docs: note secure DM guidance update (#9377) (thanks @Shrinija17) * Agents: bump pi-mono to 0.52.5 (#9949) * Agents: bump pi-mono to 0.52.5 * Changelog: add PR reference for pi bump * docs: restructure Get Started tab and improve onboarding flow (#9950) * docs: restructure Get Started tab and improve onboarding flow - Flatten nested Onboarding group into linear First Steps flow - Add 'What is OpenClaw?' narrative section to landing page - Split wizard.md into streamlined overview + full reference (reference/wizard.md) - Move Pairing to Channels > Configuration - Move Bootstrapping to Agents > Fundamentals - Move macOS app onboarding to Platforms > macOS companion app - Move Lore to Help > Community - Remove duplicate install instructions from openclaw.md - Mirror navigation changes in zh-CN tabs - No content deleted — all detail preserved or relocated * docs: move deployment pages to install/, fix Platforms tab routing, clarify onboarding paths - Move deployment guides (fly, hetzner, gcp, macos-vm, exe-dev, railway, render, northflank) from platforms/ and root to install/ - Add 'Hosting and deployment' group to Install tab - Slim Gateway & Ops 'Remote access and deployment' down to 'Remote access' - Swap Platforms tab before Gateway & Ops to fix path-prefix routing - Move macOS app onboarding into First steps (parallel to CLI wizard) - Rename sidebar titles to 'Onboarding: CLI' / 'Onboarding: macOS App' - Add redirects for all moved paths - Update all internal links (en + zh-CN) - Fix img tag syntax in onboarding.md * fix(telegram): accept messages from group members in allowlisted groups (#9775) * fix(telegram): accept messages from group members in allowlisted groups Issue #4559: Telegram bot was silently dropping messages from non-paired users in allowlisted group chats due to overly strict sender filtering. The fix adds a check to distinguish between: 1. Group itself is allowlisted → accept messages from any member 2. Group is NOT allowlisted → only accept from allowlisted senders Changes: - Check if group ID is in the allowlist (or allowlist is wildcard) - Only reject sender if they're not in allowlist AND group is not allowlisted - Improved logging to indicate the actual reason for rejection This preserves security controls while fixing the UX issue where group members couldn't participate unless individually allowlisted. Backwards compatible: existing allowlists continue to work as before. * style: format telegram fix for oxfmt compliance * refactor(telegram): clarify group allowlist semantics in fix for #4559 Changes: - Rename 'isGroupInAllowlist' to 'isGroupChatIdInAllowlist' for clarity - Expand comments to explain the semantic distinction: * Group chat ID in allowlist -> accept any group member (fixes #4559) * Group chat ID NOT in allowlist -> enforce sender allowlist (preserves security) - This addresses concerns about config semantics raised in code review The fix maintains backward compatibility: - 'groupAllowFrom' with group chat IDs now correctly acts as group enablement - 'groupAllowFrom' with sender IDs continues to work as sender allowlist - Operators should use group chat IDs for group enablement, sender IDs for sender control Note: If operators were using 'groupAllowFrom' with group IDs expecting sender-level filtering, they should migrate to a separate sender allowlist config. This is the intended behavior per issue #4559. * Telegram: allow per-group groupPolicy overrides * Telegram: support per-group groupPolicy overrides (#9775) (thanks @nicolasstanley) --------- Co-authored-by: George Pickett <gpickett00@gmail.com> * chore: remove tracked .DS_Store files * Fix: Enable scrolling on the dashboard config page (#1822) * Fix: Enable scrolling in dashboard * Fix: Enable scrolling in dashboard * Fix: Enable scrolling in dashboard * feat: add xAI Grok provider support * fix(onboard): align xAI default model to grok-4 * chore: changelog for xAI onboarding (#9885) (thanks @grp06) * fix(cron): prevent recomputeNextRuns from skipping due jobs in onTimer (#9823) * fix(cron): prevent recomputeNextRuns from skipping due jobs in onTimer ensureLoaded(forceReload) called recomputeNextRuns before runDueJobs, which recalculated nextRunAtMs to a strictly future time. Since setTimeout always fires a few ms late, the due check (now >= nextRunAtMs) always failed and every/cron jobs never executed. Fixes #9788. * docs: add changelog entry for cron timer race fix (#9823) (thanks @pycckuu) --------- Co-authored-by: Tyler Yust <TYTYYUST@YAHOO.COM> * fix(cron): re-arm timer in finally to survive transient errors (#9948) * fix(cron): handle legacy atMs field in schedule when computing next run (#9932) * fix(cron): handle legacy atMs field in schedule when computing next run The cron scheduler only checked for `schedule.at` (string) but legacy jobs may have `schedule.atMs` (number) from before the schema migration. This caused nextRunAtMs to stay null because: 1. Store migration runs on load but may not persist immediately 2. Race conditions or file mtime issues can skip migration 3. computeJobNextRunAtMs/computeNextRunAtMs only checked `at`, not `atMs` Fix: Make both functions defensive by checking `atMs` first (number), then `atMs` (string, for edge cases), then falling back to `at` (string). This ensures jobs fire correctly even if: - Migration hasn't run yet - Old data was written by a previous version - The store was manually edited Fixes #9930 * fix: validate numeric atMs to prevent NaN/Infinity propagation Addresses review feedback - numeric atMs values are now validated with Number.isFinite() && atMs > 0 before use. This prevents corrupted or manually edited stores from causing hot timer loops via setTimeout(..., NaN). * fix(exec-approvals): coerce bare string allowlist entries to objects (#9790) * fix(exec-approvals): coerce bare string allowlist entries (#9903) (thanks @mcaxtr) * security: add skill/plugin code safety scanner (#9806) * security: add skill/plugin code safety scanner module * security: integrate skill scanner into security audit * security: add pre-install code safety scan for plugins * style: fix curly brace lint errors in skill-scanner.ts * docs: add changelog entry for skill code safety scanner * style: append ellipsis to truncated evidence strings * fix(security): harden plugin code safety scanning * fix: scan skills on install and report code-safety details * fix: dedupe audit-extra import * fix(security): make code safety scan failures observable * fix(test): stabilize smoke + gateway timeouts (#9806) (thanks @abdelsfane) --------- Co-authored-by: Darshil <ddhameliya@mail.sfsu.edu> Co-authored-by: Darshil <81693876+dvrshil@users.noreply.github.com> Co-authored-by: George Pickett <gpickett00@gmail.com> * Thinking: accept extra-high alias and sync Codex FAQ wording * Changelog: note #9976 thinking alias + Codex 5.3 docs sync * fix: normalize xhigh aliases and docs sync (#9976) * fix(agents): skip tool extraction for aborted/errored assistant messages (#4598) Fixes tool call/tool_result pairing issues that cause permanent session corruption when assistant messages have stopReason "error" or "aborted". Includes 4 unit tests. * fix(cron): handle undefined sessionTarget in list output (#9649) (#9752) * fix(cron): handle undefined sessionTarget in list output (#9649) When sessionTarget is undefined, pad() would crash with 'Cannot read properties of undefined (reading trim)'. Use '-' as fallback value. * test(cron): add regression test for undefined sessionTarget (#9649) Verifies that printCronList handles jobs with undefined sessionTarget without crashing. Test fails on main branch, passes with the fix. * fix: use correct CronSchedule format in tests (#9752) (thanks @lailoo) Tests were using { kind: 'at', atMs: number } but the CronSchedule type requires { kind: 'at', at: string } where 'at' is an ISO date string. --------- Co-authored-by: damaozi <1811866786@qq.com> Co-authored-by: Tyler Yust <TYTYYUST@YAHOO.COM> * chore: Update deps. * Model: add strict gpt-5.3-codex fallback for OpenAI Codex (fixes #9989) (#9995) * Model: allow forward-compatible OpenAI Codex GPT-5 IDs * Model: scope Codex fallback to gpt-5.3-codex * fix: reorder codex fallback before providerCfg, add ordering test, changelog (#9989) (thanks @w1kke) --------- Co-authored-by: Robin <4robinlehmann@gmail.com> * fix(nextcloud-talk): sign message text instead of JSON body (#2092) Nextcloud Talk's ChecksumVerificationService verifies HMAC against the extracted message/reaction text, not the full JSON body. This fixes 401 authentication errors when sending messages via the bot API. - sendMessageNextcloudTalk: sign 'message' text only - sendReactionNextcloudTalk: sign 'reaction' string only * fix(slack): add mention stripPatterns for /new and /reset commands (#9971) * fix(slack): add mention stripPatterns for /new and /reset commands Fixes #9937 The Slack dock was missing mentions.stripPatterns that Discord has. This caused /new and /reset to fail when sent with a mention (e.g. @bot /reset) because <@USERID> wasn't stripped before matching. * fix(slack): strip mentions for /new and /reset (#9971) (thanks @ironbyte-rgb) --------- Co-authored-by: ironbyte-rgb <amontaboi76@gmail.com> Co-authored-by: George Pickett <gpickett00@gmail.com> * feat(feishu): replace built-in SDK with community plugin Replace the built-in Feishu SDK with the community-maintained clawdbot-feishu plugin by @m1heng. Changes: - Remove src/feishu/ directory (19 files) - Remove src/channels/plugins/outbound/feishu.ts - Remove src/channels/plugins/normalize/feishu.ts - Remove src/config/types.feishu.ts - Remove feishu exports from plugin-sdk/index.ts - Remove FeishuConfig from types.channels.ts New features in community plugin: - Document tools (read/create/edit Feishu docs) - Wiki tools (navigate/manage knowledge base) - Drive tools (folder/file management) - Bitable tools (read/write table records) - Permission tools (collaborator management) - Emoji reactions support - Typing indicators - Rich media support (bidirectional image/file transfer) - @mention handling - Skills for feishu-doc, feishu-wiki, feishu-drive, feishu-perm Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(feishu): add targeted eslint-disable comments for SDK integration Add line-specific eslint-disable-next-line comments for SDK type casts and union type issues, rather than file-level disables. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix(feishu): fix webhook mode silent exit and receive_id_type default - monitor.ts: throw error for webhook mode instead of silently returning, so gateway properly marks channel as failed - targets.ts: default receive_id_type to "user_id" instead of "open_id" for non-prefixed IDs, fixing message delivery for enterprise user IDs Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * chore: update pnpm-lock.yaml for feishu extension deps Add lockfile entries for: - @larksuiteoapi/node-sdk@^1.56.1 - @sinclair/typebox@0.34.47 - zod@^4.3.6 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat(feishu): sync with clawdbot-feishu #137 (multi-account support) - Sync latest changes from clawdbot-feishu including multi-account support - Add eslint-disable comments for SDK-related any types - Remove unused imports - Fix no-floating-promises in monitor.ts Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * security: redact credentials from config.get gateway responses (#9858) * security: add skill/plugin code safety scanner module * security: integrate skill scanner into security audit * security: add pre-install code safety scan for plugins * style: fix curly brace lint errors in skill-scanner.ts * docs: add changelog entry for skill code safety scanner * security: redact credentials from config.get gateway responses The config.get gateway method returned the full config snapshot including channel credentials (Discord tokens, Slack botToken/appToken, Telegram botToken, Feishu appSecret, etc.), model provider API keys, and gateway auth tokens in plaintext. Any WebSocket client—including the unauthenticated Control UI when dangerouslyDisableDeviceAuth is set—could read every secret. This adds redactConfigSnapshot() which: - Deep-walks the config object and masks any field whose key matches token, password, secret, or apiKey patterns - Uses the existing redactSensitiveText() to scrub the raw JSON5 source - Preserves the hash for change detection - Includes 15 test cases covering all channel types * security: make gateway config writes return redacted values * test: disable control UI by default in gateway server tests * fix: redact credentials in gateway config APIs (#9858) (thanks @abdelsfane) --------- Co-authored-by: George Pickett <gpickett00@gmail.com> * fix: release session locks on process termination (#1962) Adds cleanup handlers to release held file locks when the process terminates via SIGTERM, SIGINT, or normal exit. This prevents orphaned lock files that would block future sessions. Fixes #1951 * fix(ollama): add streaming config and fix OLLAMA_API_KEY env var support (#9870) * fix(ollama): add streaming config and fix OLLAMA_API_KEY env var support Adds configurable streaming parameter to model configuration and sets streaming to false by default for Ollama models. This addresses the corrupted response issue caused by upstream SDK bug badlogic/pi-mono#1205 where interleaved content/reasoning deltas in streaming responses cause garbled output. Changes: - Add streaming param to AgentModelEntryConfig type - Set streaming: false default for Ollama models - Add OLLAMA_API_KEY to envMap (was missing, preventing env var auth) - Document streaming configuration in Ollama provider docs - Add tests for Ollama model configuration Users can now configure streaming per-model and Ollama authentication via OLLAMA_API_KEY environment variable works correctly. Fixes #8839 Related: badlogic/pi-mono#1205 * docs(ollama): use gpt-oss:20b as primary example Updates documentation to use gpt-oss:20b as the primary example model since it supports tool calling. The model examples now show: - gpt-oss:20b as the primary recommended model (tool-capable) - llama3.3 and qwen2.5-coder:32b as additional options This provides users with a clear, working example that supports OpenClaw's tool calling features. * chore: remove unused vi import from ollama test * fix: untrack dist/control-ui build artifacts (#1856) The dist/control-ui/ files were committed before the dist/ gitignore rule was effective. These build artifacts get regenerated during builds, causing dirty repo errors that block the auto-update mechanism. Removes the files from git tracking while keeping them locally and respecting the existing dist/ gitignore entry. Fixes #1838 Co-authored-by: Claude <noreply@anthropic.com> * chore: add weekly upstream sync workflow Merges openclaw/openclaw main on a weekly schedule using -X ours so our fork patches always take priority. Opens a PR for visibility. Co-Authored-By: Claude <noreply@anthropic.com> * feat(gateway): route OpenAI endpoint through dispatchInboundMessage for command support * fix(gateway): remove unused import and add defensive stream close * fix(gateway): add abort on disconnect, finish_reason stop, and changelog * fix(gateway): simplify tautological ternary and split command SSE terminal chunk --------- Co-authored-by: Yeom-JinHo <81306489+Yeom-JinHo@users.noreply.github.com> Co-authored-by: Peter Steinberger <steipete@gmail.com> Co-authored-by: Lucas Kim <ichbinlucas211@gmail.com> Co-authored-by: Val Alexander <68980965+BunsDev@users.noreply.github.com> Co-authored-by: Tyler Yust <TYTYYUST@YAHOO.COM> Co-authored-by: Christian Klotz <hello@christianklotz.co.uk> Co-authored-by: Glucksberg <markuscontasul@gmail.com> Co-authored-by: Ayaan Zaidi <zaidi@uplause.io> Co-authored-by: Yudong Han <hanyd@pku.edu.cn> Co-authored-by: Iranb <49674669+Iranb@users.noreply.github.com> Co-authored-by: Seb Slight <sebslight@gmail.com> Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com> Co-authored-by: Shakker <shakkerdroid@gmail.com> Co-authored-by: Josh Palmer <joshp123@users.noreply.github.com> Co-authored-by: mudrii <mudreac@gmail.com> Co-authored-by: Gustavo Madeira Santana <gumadeiras@gmail.com> Co-authored-by: lsh411 <lsh411@gmail.com> Co-authored-by: m1 16 512 <m116512@m1ui-MacBookAir-2.local> Co-authored-by: Gustavo Madeira Santana <gumadeiras@users.noreply.github.com> Co-authored-by: Victor Mier <victormier@gmail.com> Co-authored-by: f-trycua <f@trycua.com> Co-authored-by: hyf0-agent <ada.20260202@outlook.com> Co-authored-by: hyf0-agent <hyf0-agent@users.noreply.github.com> Co-authored-by: Kelvin Calcano <kelvinr02@hotmail.com> Co-authored-by: M00N7682 <dfjk71@khu.ac.kr> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> Co-authored-by: damaozi <1811866786@qq.com> Co-authored-by: cpojer <christoph.pojer@gmail.com> Co-authored-by: sebslight <19554889+sebslight@users.noreply.github.com> Co-authored-by: Soumyadeep Ghosh <soumyadeepghosh617@gmail.com> Co-authored-by: Clawdbot <lukavyi@me.com> Co-authored-by: 大猫子 <ll1042668699@gmail.com> Co-authored-by: Rajat Joshi <78920780+18-RAJAT@users.noreply.github.com> Co-authored-by: Michael Lee <5957298+TinyTb@users.noreply.github.com> Co-authored-by: Slurpy <slurpy@openclaw.ai> Co-authored-by: 九灵云 <server@jiulingyun.cn> Co-authored-by: Tyler Yust <64381258+tyler6204@users.noreply.github.com> Co-authored-by: Caelum <subasiarhan3@gmail.com> Co-authored-by: MattQ <115874885+mattqdev@users.noreply.github.com> Co-authored-by: Omar Khaleel <bmw15925@gmail.com> Co-authored-by: Vincent Koc <vincentkoc@ieee.org> Co-authored-by: vincentkoc <vincentkoc@users.noreply.github.com> Co-authored-by: Glucksberg <80581902+Glucksberg@users.noreply.github.com> Co-authored-by: Markus Glucksberg <markus@glucksberg.com> Co-authored-by: Shrinija Kummari <shrinija@justpaid.ai> Co-authored-by: George Pickett <gpickett00@gmail.com> Co-authored-by: nicolasstanley <60584925+nicolasstanley@users.noreply.github.com> Co-authored-by: Daijiro Miyazawa <dxd5001@gmail.com> Co-authored-by: Igor Markelov <pycckuu@users.noreply.github.com> Co-authored-by: Maksym Brashchenko <39818683+j2h4u@users.noreply.github.com> Co-authored-by: fujiwara-tofu-shop <fujiwara@foundnone.xyz> Co-authored-by: Marcus Castro <mcaxtr@gmail.com> Co-authored-by: Abdel Sy Fane <32418586+abdelsfane@users.noreply.github.com> Co-authored-by: Darshil <ddhameliya@mail.sfsu.edu> Co-authored-by: Darshil <81693876+dvrshil@users.noreply.github.com> Co-authored-by: slonce70 <slonce70@gmail.com> Co-authored-by: Aisling Cahill <aisling@telnyx.com> Co-authored-by: Robin <4robinlehmann@gmail.com> Co-authored-by: wangai-studio <256938352+wangai-studio@users.noreply.github.com> Co-authored-by: ironbyte-rgb <amtaboi76@gmail.com> Co-authored-by: ironbyte-rgb <amontaboi…
* Fix missing before_tool_call hook integration (#6570)
* Fix missing before_tool_call hook integration
- Add hook call in handleToolExecutionStart before tool execution begins
- Support parameter modification via hookResult.params
- Support tool call blocking via hookResult.block with custom blockReason
- Fix try/catch logic to properly re-throw blocking errors using __isHookBlocking flag
- Maintain tool event consistency by emitting start/end events when blocked
- Addresses GitHub issue #6535 (1 of 8 unimplemented hooks now working)
Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
* Add comprehensive test suite for before_tool_call hook
- 9 tests covering all hook scenarios: no hooks, parameter passing, modification, blocking, error handling
- Tests tool name normalization and different argument types
- Verifies proper error re-throwing and logging behavior
- Maintained in fork for regression testing
* Fix all issues identified by Greptile code review
Address P0/P1/P3 bugs:
P0 - Fix parameter mutation crash for non-object args:
- Normalize args to objects before passing to hooks (maintains hook contract)
- Handle parameter merging safely for both object and non-object args
P1 - Add missing internal state updates when blocking tools:
- Set toolMetaById metadata like normal flow
- Call onAgentEvent callback to maintain consistency
- Emit events in same order as normal tool execution
P1 - Fix test expectations to match implementation reality:
- Non-object args normalized to {} for hook params (not passed as-is)
- Add test for safe parameter modification with various arg types
- Update mocks to verify state updates when blocking
P3 - Replace magic __isHookBlocking property with dedicated ToolBlockedError class:
- More robust error handling without property collision risk
- Cleaner control flow that's serialization-safe
Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4 <noreply@anthropic.com>
(cherry picked from commit 6c6f1e9660bd81424a25a9a4d1a9c66b9bae5a6c)
* feat: extend CreateAgentSessionOptions with new properties
- Added systemPrompt for overriding the default system prompt.
- Introduced skills for pre-loaded skills management.
- Added contextFiles for handling pre-loaded context files with path and content attributes.
(cherry picked from commit bcbb4473573d89beb9a2e028db05d59325a0d74e)
* feat: update chat layout and session management
- Added max-width to chat controls and session select for better layout.
- Increased CHAT_SESSIONS_ACTIVE_MINUTES from 10 to 120 for extended session duration.
- Changed brand logo source to a local favicon for improved asset management.
(cherry picked from commit f8575c401cc0577f905b9efa320bbd50fff1ac2e)
# Conflicts:
# ui/src/ui/app-render.ts
* require TLS 1.3 as minimum
TLS 1.2 is not getting any protocol update anytime soon.
https://www.ietf.org/archive/id/draft-ietf-tls-tls12-frozen-08.html
(cherry picked from commit a2b00495cdcea73dc24e3f2908ede32778b20264)
* fix(tlon): add timeout to SSE client fetch calls (CWE-400) (#5926)
Add timeout protection to prevent indefinite hangs when Urbit server
becomes unresponsive or network partition occurs.
Changes:
- Add AbortSignal.timeout(30_000) to 7 one-shot fetch calls
- Add AbortController with 60s connection timeout to SSE stream fetch
(clears timeout after headers received to avoid aborting active stream)
Affected methods: sendSubscription, connect, openStream, poke, scry, close
Fixes #5266
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
(cherry picked from commit 411d5fda587c5ae44735550f9a23fe224de5da9f)
* Gateway: avoid writing host config in tools invoke test
(cherry picked from commit 476f367cf16081acd144048ee61198e58d15df21)
# Conflicts:
# src/gateway/tools-invoke-http.test.ts
* Docs: fix Moonshot sync markers (#6789)
* Docs: fix Moonshot sync markers
* Docs: use MDX comment markers for Moonshot sync
* Docs: use markdown comment markers for Moonshot sync
* Docs: hide Moonshot sync markers in MDX
(cherry picked from commit b9910ab03713d2598a5d4fcbf95c9dc935064b68)
# Conflicts:
# docs/providers/moonshot.md
* chore: lint the `ui` folder.
(cherry picked from commit 5ba4586e587fc4a378e2791b240aff3a9c6aa666)
# Conflicts:
# ui/src/ui/app-gateway.ts
# ui/src/ui/app-polling.ts
# ui/src/ui/app-settings.ts
# ui/src/ui/controllers/chat.ts
* chore: Manually fix lint issues in `ui`.
(cherry picked from commit e9a32b83c2b59392585e25caee61ddd073b0f6ef)
# Conflicts:
# ui/src/ui/app-gateway.ts
# ui/src/ui/app-polling.ts
# ui/src/ui/app-render.ts
# ui/src/ui/app-settings.ts
# ui/src/ui/chat-markdown.browser.test.ts
# ui/src/ui/controllers/chat.ts
# ui/src/ui/focus-mode.browser.test.ts
# ui/src/ui/navigation.browser.test.ts
# ui/vite.config.ts
* chore: Re-enable `no-redundant-type-constituents` rule.
(cherry picked from commit 87a61c3b88af25dca5a0d422a4155dcf58f9dc54)
* chore: Enable `no-unnecessary-template-expression` lint rule.
(cherry picked from commit baa1e95b9d9401c5916e0218e42196a8edc0e5e2)
* chore: Enable `typescript/no-explicit-any` rule.
(cherry picked from commit 935a0e57083d94590f742c587bdbfbad9ea3139c)
# Conflicts:
# extensions/lobster/src/lobster-tool.test.ts
# src/agents/auth-profiles/oauth.ts
# src/agents/pi-tools.before-tool-call.test.ts
# src/discord/monitor/sender-identity.ts
# src/telegram/draft-stream.test.ts
* fix(telegram): add timeout to file download to prevent DoS (CWE-400)
Add AbortSignal.timeout() to both fetch calls in download.ts to prevent
indefinite hangs when Telegram API is slow or unresponsive.
- getTelegramFile(): 30s timeout for metadata API call
- downloadTelegramFile(): 60s timeout for file download
Both functions now accept optional timeoutMs parameter for configurability.
Fixes #6849
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
(cherry picked from commit d46b489e21c7b6cd9549baa5971d47382ab54b6b)
* Fix subagent announce failover race (always emit lifecycle end + treat timeout=0 as no-timeout) (#6621)
* Fix subagent announce race and timeout handling
Bug 1: Subagent announce fires before model failover retries finish
- Problem: CLI provider emitted lifecycle error on each attempt, causing
subagent registry to prematurely call beginSubagentCleanup() and announce
with incorrect status before failover retries completed
- Fix: Removed lifecycle error emission from CLI provider's attempt-level
.catch() in agent-runner-execution.ts. Errors still propagate to
runWithModelFallback for retry, but no intermediate lifecycle events
are emitted. Only the final outcome (after all retries) emits lifecycle
events.
Bug 2: Hard 600s per-prompt timeout ignores runTimeoutSeconds=0
- Problem: When runTimeoutSeconds=0 (meaning 'no timeout'), the code
returned the default 600s timeout instead of respecting the 0 setting
- Fix: Modified resolveAgentTimeoutMs() to treat 0 as 'no timeout' and
return a very large timeout value (30 days) instead of the default.
This avoids setTimeout issues with Infinity while effectively providing
unlimited time for long-running tasks.
* fix: emit lifecycle:error for CLI failures (#6621) (thanks @tyler6204)
* chore: satisfy format/lint gates (#6621) (thanks @tyler6204)
* fix: restore build after upstream type changes (#6621) (thanks @tyler6204)
* test: fix createSystemPromptOverride tests to match new return type (#6621) (thanks @tyler6204)
(cherry picked from commit 8d2f98fb01a6eb3fdb8b30645917ff4fde971f35)
# Conflicts:
# extensions/bluebubbles/src/monitor.ts
# extensions/matrix/CHANGELOG.md
# extensions/msteams/CHANGELOG.md
# extensions/nostr/CHANGELOG.md
# extensions/twitch/CHANGELOG.md
# extensions/voice-call/CHANGELOG.md
# extensions/zalo/CHANGELOG.md
# extensions/zalouser/CHANGELOG.md
# src/agents/auth-profiles/oauth.ts
# src/agents/pi-embedded-runner/system-prompt.ts
* docs: update appcast for 2026.2.1
(cherry picked from commit d842b28a1517f95aae2a5bcd97f2f726e42b93d8)
# Conflicts:
# appcast.xml
* style: format fetch guard signatures
(cherry picked from commit 1b3f987c4d45906e530c3266d2a7465ad18e3dc7)
* fix(docker): add gateway subcommand and cloud-compatible flags
The Dockerfile CMD runs without arguments, causing the CLI to print
help and exit with code 1. This breaks deployment on container
platforms (Render, Railway, Fly.io, etc.) that rely on the CMD.
Changes:
- Add `gateway` subcommand to start the server
- Add `--allow-unconfigured` to allow startup without config file
- Add `--bind lan` to bind to 0.0.0.0 instead of localhost
(required for container health checks)
Fixes #5685
(cherry picked from commit 1a05ee941e7df648cd8349237cde824341a1bbdb)
* fix(docker): remove --bind lan from default CMD to work out of the box
Addresses review feedback: --bind lan requires auth token, so default
CMD should bind to loopback only.
For container platforms needing LAN binding for health checks:
1. Set OPENCLAW_GATEWAY_TOKEN env var
2. Override CMD: ["node","dist/index.js","gateway","--allow-unconfigured","--bind","lan"]
(cherry picked from commit bb3d7343f4befc45be548ab72890eef62193b020)
* test: cover SSRF blocking for attachment URLs
(cherry picked from commit 39c682219e4f359eeb14cf98e1bbabcf9f504547)
* chore: We have a sleep at home. The sleep at home:
(cherry picked from commit 6b0d6e25405b98f29cbdd0a8b77674b3c294ee73)
# Conflicts:
# src/agents/bash-tools.exec.background-abort.test.ts
# src/agents/bash-tools.process.send-keys.test.ts
# src/agents/claude-cli-runner.test.ts
# src/agents/clawdbot-tools.sessions.test.ts
# src/agents/clawdbot-tools.subagents.sessions-spawn-announces-agent-wait-lifecycle-events.test.ts
# src/agents/clawdbot-tools.subagents.sessions-spawn-normalizes-allowlisted-agent-ids.test.ts
# src/auto-reply/reply/reply-dispatcher.ts
# src/channels/ack-reactions.test.ts
# src/config/sessions.test.ts
# src/slack/monitor/media.ts
# src/web/auto-reply/deliver-reply.ts
* fix(update): harden global updates
(cherry picked from commit 57d008a33d4208c81183384d47f938d69b7c7044)
# Conflicts:
# CHANGELOG.md
# src/infra/update-global.ts
# src/infra/update-runner.ts
* chore: fix broken test.
(cherry picked from commit c429ccb64fc319babf4f8adc95df6d658a2d6b2f)
* fix(telegram): handle Grammy HttpError network failures (#3815) (#7195)
* fix(telegram): handle Grammy HttpError network failures (#3815)
Grammy wraps fetch errors in an .error property (not .cause). Added .error
traversal to collectErrorCandidates in network-errors.ts.
Registered scoped unhandled rejection handler in monitorTelegramProvider
to catch network errors that escape the polling loop (e.g., from setMyCommands
during bot setup). Handler is unregistered when the provider stops.
* fix(telegram): address review feedback for Grammy HttpError handling
- Gate .error traversal on HttpError name to avoid widening search graph
- Use runtime logger instead of console.warn for consistency
- Add isGrammyHttpError check to scope unhandled rejection handler
- Consolidate isNetworkRelatedError into isRecoverableTelegramNetworkError
- Add 'timeout' to recoverable message snippets for full coverage
(cherry picked from commit 99b4f2a24e9ec38ca1624757f7df35459bfa67a0)
# Conflicts:
# src/telegram/monitor.ts
* Docs i18n: harden doc-mode pipeline
(cherry picked from commit e70984745be336cbb9f4bc227a9f9a229d5efa46)
* Docs i18n: tune zh-CN prompt + glossary
What: enforce zh-CN tone (你/你的), Skills/local loopback/Tailscale terms, Gateway网关
Why: keep future translation output consistent with issue feedback
Tests: not run (prompt/glossary change)
(cherry picked from commit 2b1f68c92863589f3a4fa7bf96f242936eec8a5e)
* Tests: stub SSRF DNS pinning (#6619) (thanks @joshp123)
(cherry picked from commit 991ed3ab5843fb808c4c92faafde54dda19b3137)
# Conflicts:
# CHANGELOG.md
# src/media-understanding/providers/google/video.test.ts
* fix(webchat): respect user scroll position during streaming and refresh
- Increase near-bottom threshold from 200px to 450px so one long message
doesn't falsely register as 'near bottom'
- Make force=true only override on initial load (chatHasAutoScrolled=false),
not on subsequent refreshChat() calls
- refreshChat() no longer passes force=true to scheduleChatScroll
- Add chatNewMessagesBelow flag for future 'scroll to bottom' button UI
- Clear chatNewMessagesBelow when user scrolls back to bottom
- Add 13 unit tests covering threshold, force behavior, streaming, and reset
(cherry picked from commit e18f43ddade6cffd178550cdd7c306f841f3b7d6)
* fix(ui): add core state and logic for scroll control
(cherry picked from commit 2af977f947c9f3c9964e0d0fe1b8f371392cfbf1)
# Conflicts:
# ui/src/ui/app.ts
* feat(ui): add new messages indicator button
(cherry picked from commit 13db0489c871ff2b0da3a9d0563524137aecf9e1)
* iOS: stabilize talk mode tests
(cherry picked from commit 78f7e5147becb2d7ee3c8cfa748700bc080aa00c)
* Gateway: fix node invoke receive loop
(cherry picked from commit 84e115834fa27a9954f48d61a794b25b9187e6e4)
# Conflicts:
# apps/ios/Sources/Gateway/GatewayConnectionController.swift
# apps/ios/Sources/Gateway/GatewaySettingsStore.swift
# apps/shared/MoltbotKit/Sources/MoltbotKit/GatewayChannel.swift
# apps/shared/MoltbotKit/Tests/MoltbotKitTests/GatewayNodeInvokeTests.swift
* Gateway: wait for snapshot before connect
(cherry picked from commit a4382607d7a8752ed88ad9fc8ba11fae6bc620c0)
* Agents: add nodes invoke action
(cherry picked from commit d9cadf97377812e53b87a15082c74efc67e5e662)
* iOS: fix node notify and identity
(cherry picked from commit 761188cd1d48527c8039c087b5be820ec0a67691)
# Conflicts:
# apps/ios/Sources/Model/NodeAppModel.swift
# apps/ios/SwiftSources.input.xcfilelist
* iOS: streamline notify timeouts
(cherry picked from commit f72ac60b01f166d3b168f70a56211e11c8d19034)
# Conflicts:
# apps/ios/Sources/Gateway/GatewayConnectionController.swift
# apps/ios/Sources/Model/NodeAppModel.swift
* iOS: add write commands for contacts/calendar/reminders
(cherry picked from commit a884955cd6d442a589e501516a1a5ddd0c91ccf9)
# Conflicts:
# apps/ios/Sources/Calendar/CalendarService.swift
# apps/ios/Sources/Contacts/ContactsService.swift
# apps/ios/Sources/Gateway/GatewayConnectionController.swift
# apps/ios/Sources/Info.plist
# apps/ios/Sources/Model/NodeAppModel.swift
# apps/ios/Sources/Reminders/RemindersService.swift
# apps/ios/Sources/Services/NodeServiceProtocols.swift
# apps/ios/Tests/GatewayConnectionControllerTests.swift
# apps/ios/Tests/NodeAppModelInvokeTests.swift
# apps/shared/OpenClawKit/Sources/OpenClawKit/CalendarCommands.swift
# apps/shared/OpenClawKit/Sources/OpenClawKit/ContactsCommands.swift
# apps/shared/OpenClawKit/Sources/OpenClawKit/RemindersCommands.swift
* iOS: add push-to-talk node commands
(cherry picked from commit 9f101d3a9aaeaefb6873e27bc2a5ef9129c51fd0)
# Conflicts:
# apps/ios/Sources/Gateway/GatewayConnectionController.swift
# apps/ios/Sources/Model/NodeAppModel.swift
# apps/ios/SwiftSources.input.xcfilelist
# apps/ios/Tests/NodeAppModelInvokeTests.swift
* iOS: pause voice wake during PTT
(cherry picked from commit 17b18971f17c4cb4ad0e2d302bf8ac614cc77a42)
* iOS: add PTT once/cancel
(cherry picked from commit 1a48bce2947ea2f0ebd923d790322cb3f5035e0b)
# Conflicts:
# apps/ios/Sources/Gateway/GatewayConnectionController.swift
# apps/ios/Tests/NodeAppModelInvokeTests.swift
* Gateway: add PTT chat + nodes CLI
(cherry picked from commit b7aac92ac4511683c4bf44f4119496227286f909)
# Conflicts:
# src/auto-reply/reply/commands-core.ts
* iOS: wire node commands and incremental TTS
(cherry picked from commit 532b9653beed121300fd5decb18125f73bb1e13d)
# Conflicts:
# apps/ios/Sources/Gateway/GatewayConnectionController.swift
# apps/ios/Sources/Model/NodeAppModel.swift
# apps/ios/Sources/Voice/TalkModeManager.swift
# apps/ios/Tests/NodeAppModelInvokeTests.swift
* iOS: update onboarding and gateway UI
(cherry picked from commit ff6114599ef9f85d4cf50fec5e61053bfd09192d)
# Conflicts:
# apps/ios/Sources/Info.plist
# apps/ios/Sources/Model/NodeAppModel.swift
* Core: update shared gateway models
(cherry picked from commit 37eaca719a68aa1ad9dcbfe83c8a20e88bb6951a)
* iOS: improve gateway auto-connect and voice permissions
(cherry picked from commit 6cd3bc3a46f3b1e7ca38673db236ab11bdd6ff00)
# Conflicts:
# IOS-PRIORITIES.md
# src/auto-reply/reply/commands-core.ts
* Revert "iOS: wire node services and tests"
This reverts commit 7b0a0f3dace575c33dafb61d4a13cdef4dd0d64e.
(cherry picked from commit 4ab814fd50c677c4658418ced2a8fb99a19928d2)
# Conflicts:
# apps/ios/Sources/Gateway/GatewayConnectionController.swift
# apps/ios/Sources/Gateway/GatewaySettingsStore.swift
# apps/ios/Sources/Model/NodeAppModel.swift
# apps/ios/Sources/Voice/TalkModeManager.swift
# apps/ios/SwiftSources.input.xcfilelist
# apps/ios/Tests/GatewayConnectionControllerTests.swift
# apps/ios/Tests/NodeAppModelInvokeTests.swift
# apps/shared/MoltbotKit/Sources/MoltbotKit/GatewayChannel.swift
# apps/shared/MoltbotKit/Tests/MoltbotKitTests/GatewayNodeInvokeTests.swift
# apps/shared/OpenClawKit/Sources/OpenClawKit/Capabilities.swift
# src/auto-reply/reply/commands-core.ts
* Revert "Core: update shared gateway models"
This reverts commit 37eaca719a68aa1ad9dcbfe83c8a20e88bb6951a.
(cherry picked from commit 7113dc21a909970098674e3b04d2c74617e9a307)
* feat(config): default thinking for sessions_spawn subagents (#7372)
* feat(config): add subagent default thinking
* fix: accept config subagents.thinking + stabilize test mocks (#7372) (thanks @tyler6204)
* fix: use findLast instead of clearAllMocks in test (#7372)
* fix: correct test assertions for tool result structure (#7372)
* fix: remove unnecessary type assertion after rebase
(cherry picked from commit 64849e81f5ae96f46fa6f19d65cf5ec8d37c18ed)
# Conflicts:
# CHANGELOG.md
# docs/zh-CN/tools/subagents.md
* refactor: use structural typing instead of instanceof for AbortSignal check
Address P1 review feedback from Greptile: instanceof AbortSignal may be
unreliable across different realms (VM, iframe, etc.) where the AbortSignal
constructor may differ. Use structural typing (checking for aborted property
and addEventListener method) for more robust cross-realm compatibility.
(cherry picked from commit 88e29c728c203eab13b25a46ba9c05ed7443d8f3)
# Conflicts:
# src/agents/pi-tools.abort.ts
* fix(tools): ensure file_path alias passes validation in read/write tools (#7451)
Co-authored-by: lotusfall <lotusfall@outlook.com>
(cherry picked from commit 966228a6a90a5693620a430b2bb299f1bdd7adb9)
* fix(telegram): recover from grammY "timed out" long-poll errors (#7239)
grammY getUpdates returns "Request to getUpdates timed out after 500 seconds"
but RECOVERABLE_MESSAGE_SNIPPETS only had "timeout". Since
"timed out".includes("timeout") === false, the error was not classified as
recoverable, causing the polling loop to exit permanently.
Add "timed out" to RECOVERABLE_MESSAGE_SNIPPETS so the polling loop retries
instead of dying silently.
Fixes #7239
Fixes #7255
(cherry picked from commit c6b4de520af848bdfa577146aa8e2e001c87911d)
* Agent: repair malformed tool calls and session files
(cherry picked from commit 0da6de6624a955785136a676aa99aff6b8f4de95)
# Conflicts:
# src/agents/pi-embedded-runner/google.ts
# src/agents/pi-embedded-runner/run/attempt.ts
# src/agents/session-tool-result-guard.ts
* Agents: fix lint in tool-call sanitizers
(cherry picked from commit 67f90dae543e06d132c81a0aff13329da5931e67)
* Agents: harden session file repair
(cherry picked from commit e6fdac7bfb6d15d8b9b1f347f1039dded9fa35a1)
* Agents: flush pending tool results on drop
(cherry picked from commit befa421a57cf4f83cb220e3032e1847a6d12f365)
* fix(slack): fail closed on slash command channel type lookup
(cherry picked from commit fff59da962145088246864e735c5f3a6f1b67a7f)
# Conflicts:
# CHANGELOG.md
# src/slack/monitor/slash.ts
* fix(gateway): require shared auth before device bypass
(cherry picked from commit fe81b1d7125a014b8280da461f34efbf5f761575)
# Conflicts:
# CHANGELOG.md
* style(ui): format resizable divider
(cherry picked from commit 96ad19a627ba14b5770ee3be8cee37eeae4aa230)
* chore: Fix CI.
(cherry picked from commit e77988f7471d35bc42f0c749dde8140a1cad4e27)
* feat(ui): add Agents dashboard
(cherry picked from commit 2a68bcbeb32e2fa14282639ca17574d48a21fe2d)
# Conflicts:
# src/agents/agent-scope.ts
# src/gateway/server-methods/agents.ts
# src/gateway/server-methods/skills.ts
# ui/src/ui/app-settings.ts
# ui/src/ui/app.ts
* chore: fix CI
(cherry picked from commit ac2b71f24033f7d7b3ba8eb5c46c30c374290815)
* CLI: restore terminal state on exit
(cherry picked from commit 157d6d2db7e004ca4bfa1dfd0142d5bbd6aa8e45)
* Onboarding: keep TUI flow exclusive
(cherry picked from commit 58d5b39c9aa635b08ce08d03ef0f17ec0908e1f2)
# Conflicts:
# CHANGELOG.md
# src/wizard/onboarding.finalize.ts
* feat (memory): Implement new (opt-in) QMD memory backend
(cherry picked from commit 5d3af3bc6226026826c5eef48e2ad2eb9f6a01f2)
# Conflicts:
# docs/concepts/memory.md
# src/agents/pi-embedded-runner/system-prompt.ts
# src/agents/system-prompt.ts
# src/agents/tools/memory-tool.ts
# src/commands/status.scan.ts
# src/config/zod-schema.ts
# src/memory/manager.ts
# src/memory/search-manager.ts
* Make memory more resilient to failure
(cherry picked from commit 2c30ba400bbddfee9929e149003f5eccfbe86813)
* Add more tests; make fall back more resilient and visible
(cherry picked from commit 3a57106c1e8e95e488e94152f1fac62e72644b75)
# Conflicts:
# CHANGELOG.md
* Fix build errors
(cherry picked from commit e12184661e9bdfa4cb80987f6fb9db7562285d39)
* fix(qmd): use XDG dirs for qmd home; drop ollama docs
(cherry picked from commit 9be3c27bb7597084b0e547f8185c298495f02976)
* fix(memory-qmd): write XDG index.yml + legacy compat
(cherry picked from commit dd8373a4241a50b10e7a2cc66d9a41c28ca3acad)
# Conflicts:
# src/memory/search-manager.ts
* fix(memory-qmd): create collections via qmd CLI (no YAML)
(cherry picked from commit 564fe6f08957c6cc8bc1973f6420a184f4a18fdb)
* fix(memory/qmd): throttle embed + citations auto + restore --force
(cherry picked from commit 9df78b337900983462ff98261d0e09280d294d89)
* Tests: use OPENCLAW_STATE_DIR in qmd manager
(cherry picked from commit 5d8c665baffda9cefb900a96c3b7c1ae24f328c7)
* Memory: parse quoted qmd command
(cherry picked from commit 3e82cbd55bca40780b3f2a374b638672e8ef612f)
* Memory: fix QMD scope channel parsing
(cherry picked from commit b7f4755020965877ec1b91112f7d5eaf1a8b3677)
* Memory: harden QMD memory_get path checks
(cherry picked from commit c248da031794bc74f430c68071f8382392d2e4c0)
* Memory: clamp QMD citations to injected budget
(cherry picked from commit 1861e76360407981ced3027a4df68a01b4114baf)
# Conflicts:
# src/agents/tools/memory-tool.ts
* Tests: cover QMD scope, reads, and citation clamp
(cherry picked from commit 3d1c3b78ec2be947f43f9f91d94cefd27149071f)
* QMD: use OpenClaw config types
(cherry picked from commit 465536e811690530d3dfab52098a20b82a724c4c)
* Lint: add braces for single-line ifs
(cherry picked from commit e332a717a8d118680d7b3bc0f2ba981a28952980)
* chore: apply formatter
(cherry picked from commit 9bef525944a034aafb76231203e495b27e1a20ac)
# Conflicts:
# docs/concepts/memory.md
# src/agents/system-prompt.ts
# src/agents/tools/memory-tool.ts
# src/commands/status.scan.ts
# src/memory/search-manager.ts
* chore: restore OpenClaw branding
(cherry picked from commit f72214725d6bdde8ff6bc0550524a113555a0664)
# Conflicts:
# docs/concepts/memory.md
# src/agents/system-prompt.ts
# src/agents/tools/memory-tool.ts
# src/memory/search-manager.ts
* chore: fix lint warnings
(cherry picked from commit 30098b04d7298407a9eb8b2896f33e891b74d542)
# Conflicts:
# src/agents/system-prompt.ts
# src/agents/tools/memory-tool.ts
# src/memory/search-manager.ts
* chore: oxfmt
(cherry picked from commit 5915d479dca92acbe43962bc58e6a1d1781a9901)
# Conflicts:
# src/agents/tools/memory-tool.ts
* chore: oxfmt
(cherry picked from commit 600c46b5a4a963e036f78f1ba5da24f0e4748eae)
# Conflicts:
# src/agents/system-prompt.ts
* CLI: cache shell completion scripts
(cherry picked from commit 80d8fe778602c5a2a21632a96134796ba21adef7)
* Install: cache completion scripts on install/update
(cherry picked from commit 9950440cf6dea3cb11da2bfd32bc92c7d6aa0ab8)
* Onboarding: drop completion prompt
(cherry picked from commit 981de051813ae9b2b406d89d119cd6a8346238a2)
# Conflicts:
# src/wizard/onboarding.ts
* feat: remove slop.
(cherry picked from commit 6fb2d3d7d72773182986e41bf8b5d38c871447b1)
# Conflicts:
# docs/install/index.md
# package.json
# packages/clawdbot/package.json
# scripts/docker/cleanup-smoke/Dockerfile
# scripts/postinstall.js
# src/postinstall-patcher.test.ts
* chore: clean up git hooks and actually install them again.
(cherry picked from commit 6b83d82e82912484cb986ed15af39d5a6ff376eb)
# Conflicts:
# docs/zh-CN/scripts.md
# scripts/docker/cleanup-smoke/Dockerfile
# scripts/format-staged.js
# scripts/setup-git-hooks.js
# src/git-hooks.test.ts
* chore: Fix all TypeScript errors in `ui`.
(cherry picked from commit 27677dd8bd37c31cbf04e0ce9802b050ed59a2de)
# Conflicts:
# ui/src/ui/app-render.helpers.ts
# ui/src/ui/app-render.ts
* chore: Switch to `NodeNext` for `module`/`moduleResolution` in `ui`.
(cherry picked from commit 6e09c1142eeca3f01a6b5ab1e390c92ddb841e73)
# Conflicts:
# ui/src/ui/app-channels.ts
# ui/src/ui/app-chat.ts
# ui/src/ui/app-gateway.ts
# ui/src/ui/app-lifecycle.ts
# ui/src/ui/app-polling.ts
# ui/src/ui/app-render.helpers.ts
# ui/src/ui/app-render.ts
# ui/src/ui/app-settings.test.ts
# ui/src/ui/app-settings.ts
# ui/src/ui/app-view-state.ts
# ui/src/ui/app.ts
# ui/src/ui/chat-markdown.browser.test.ts
# ui/src/ui/chat/grouped-render.ts
# ui/src/ui/chat/tool-cards.ts
# ui/src/ui/config-form.browser.test.ts
# ui/src/ui/controllers/chat.test.ts
# ui/src/ui/controllers/chat.ts
# ui/src/ui/controllers/cron.ts
# ui/src/ui/controllers/devices.ts
# ui/src/ui/controllers/sessions.ts
# ui/src/ui/focus-mode.browser.test.ts
# ui/src/ui/format.test.ts
# ui/src/ui/gateway.ts
# ui/src/ui/markdown.test.ts
# ui/src/ui/navigation.browser.test.ts
# ui/src/ui/presenter.ts
# ui/src/ui/tool-display.ts
# ui/src/ui/uuid.test.ts
# ui/src/ui/views/channels.config.ts
# ui/src/ui/views/channels.discord.ts
# ui/src/ui/views/channels.googlechat.ts
# ui/src/ui/views/channels.imessage.ts
# ui/src/ui/views/channels.nostr-profile-form.ts
# ui/src/ui/views/channels.nostr.ts
# ui/src/ui/views/channels.shared.ts
# ui/src/ui/views/channels.signal.ts
# ui/src/ui/views/channels.slack.ts
# ui/src/ui/views/channels.telegram.ts
# ui/src/ui/views/channels.ts
# ui/src/ui/views/channels.whatsapp.ts
# ui/src/ui/views/chat.test.ts
# ui/src/ui/views/chat.ts
# ui/src/ui/views/config-form.render.ts
# ui/src/ui/views/config.browser.test.ts
# ui/src/ui/views/cron.test.ts
# ui/src/ui/views/cron.ts
# ui/src/ui/views/debug.ts
# ui/src/ui/views/exec-approval.ts
# ui/src/ui/views/gateway-url-confirmation.ts
# ui/src/ui/views/instances.ts
# ui/src/ui/views/logs.ts
# ui/src/ui/views/markdown-sidebar.ts
# ui/src/ui/views/nodes.ts
# ui/src/ui/views/overview.ts
# ui/src/ui/views/sessions.ts
# ui/src/ui/views/skills.ts
* chore: Merge tsconfigs, typecheck `ui` as part of `pnpm tsgo` locally and on CI.
(cherry picked from commit 1f2f79a7a7c147f14a46a024ceb333447201dd81)
# Conflicts:
# tsconfig.json
* fix(ui): fix web UI after tsdown migration and typing changes
(cherry picked from commit 5935c4d23d5e3a4d521df99e5d419fb4f8690557)
# Conflicts:
# docs/zh-CN/gateway/configuration.md
# src/agents/skills/bundled-dir.ts
# src/config/schema.ts
# src/gateway/control-ui.ts
# src/gateway/server-http.ts
# src/gateway/server.impl.ts
# src/infra/control-ui-assets.test.ts
# src/infra/control-ui-assets.ts
# tsconfig.json
* fix(skills): warn when bundled dir missing
(cherry picked from commit f60eae83fade776fadf7822a6420967f8e58b6fa)
# Conflicts:
# CHANGELOG.md
* fix(ui): refresh agent files after external edits
(cherry picked from commit ddccfd3ec1cfea9ba5908fd3cae53fd5f48772a5)
* Docs: update zh-CN translations and pipeline
What:
- update zh-CN glossary, TM, and translator prompt
- regenerate zh-CN docs and apply targeted fixes
- add zh-CN AGENTS pipeline guidance
Why:
- address terminology/spacing feedback from #6995
Tests:
- pnpm build && pnpm check && pnpm test
(cherry picked from commit a3ec2d073494cc7227820509b103f1de56375451)
# Conflicts:
# docs/zh-CN/automation/auth-monitoring.md
# docs/zh-CN/automation/cron-jobs.md
# docs/zh-CN/automation/gmail-pubsub.md
# docs/zh-CN/automation/poll.md
# docs/zh-CN/automation/webhook.md
# docs/zh-CN/bedrock.md
# docs/zh-CN/brave-search.md
# docs/zh-CN/broadcast-groups.md
# docs/zh-CN/channels/bluebubbles.md
# docs/zh-CN/channels/discord.md
# docs/zh-CN/channels/googlechat.md
# docs/zh-CN/channels/grammy.md
# docs/zh-CN/channels/imessage.md
# docs/zh-CN/channels/index.md
# docs/zh-CN/channels/line.md
# docs/zh-CN/channels/matrix.md
# docs/zh-CN/channels/mattermost.md
# docs/zh-CN/channels/msteams.md
# docs/zh-CN/channels/nextcloud-talk.md
# docs/zh-CN/channels/nostr.md
# docs/zh-CN/channels/signal.md
# docs/zh-CN/channels/slack.md
# docs/zh-CN/channels/telegram.md
# docs/zh-CN/channels/tlon.md
# docs/zh-CN/channels/twitch.md
# docs/zh-CN/channels/whatsapp.md
# docs/zh-CN/channels/zalo.md
# docs/zh-CN/channels/zalouser.md
# docs/zh-CN/cli/acp.md
# docs/zh-CN/cli/agent.md
# docs/zh-CN/cli/approvals.md
# docs/zh-CN/cli/browser.md
# docs/zh-CN/cli/channels.md
# docs/zh-CN/cli/config.md
# docs/zh-CN/cli/configure.md
# docs/zh-CN/cli/cron.md
# docs/zh-CN/cli/devices.md
# docs/zh-CN/cli/dns.md
# docs/zh-CN/cli/docs.md
# docs/zh-CN/cli/doctor.md
# docs/zh-CN/cli/gateway.md
# docs/zh-CN/cli/health.md
# docs/zh-CN/cli/hooks.md
# docs/zh-CN/cli/index.md
# docs/zh-CN/cli/logs.md
# docs/zh-CN/cli/node.md
# docs/zh-CN/cli/nodes.md
# docs/zh-CN/cli/onboard.md
# docs/zh-CN/cli/pairing.md
# docs/zh-CN/cli/plugins.md
# docs/zh-CN/cli/sandbox.md
# docs/zh-CN/cli/security.md
# docs/zh-CN/cli/skills.md
# docs/zh-CN/cli/status.md
# docs/zh-CN/cli/system.md
# docs/zh-CN/cli/tui.md
# docs/zh-CN/cli/uninstall.md
# docs/zh-CN/cli/update.md
# docs/zh-CN/concepts/agent-loop.md
# docs/zh-CN/concepts/agent-workspace.md
# docs/zh-CN/concepts/agent.md
# docs/zh-CN/concepts/architecture.md
# docs/zh-CN/concepts/context.md
# docs/zh-CN/concepts/group-messages.md
# docs/zh-CN/concepts/groups.md
# docs/zh-CN/concepts/memory.md
# docs/zh-CN/concepts/messages.md
# docs/zh-CN/concepts/model-failover.md
# docs/zh-CN/concepts/model-providers.md
# docs/zh-CN/concepts/models.md
# docs/zh-CN/concepts/multi-agent.md
# docs/zh-CN/concepts/presence.md
# docs/zh-CN/concepts/queue.md
# docs/zh-CN/concepts/session-pruning.md
# docs/zh-CN/concepts/session-tool.md
# docs/zh-CN/concepts/session.md
# docs/zh-CN/concepts/streaming.md
# docs/zh-CN/concepts/system-prompt.md
# docs/zh-CN/concepts/typebox.md
# docs/zh-CN/debugging.md
# docs/zh-CN/diagnostics/flags.md
# docs/zh-CN/environment.md
# docs/zh-CN/experiments/onboarding-config-protocol.md
# docs/zh-CN/experiments/plans/cron-add-hardening.md
# docs/zh-CN/experiments/plans/group-policy-hardening.md
# docs/zh-CN/experiments/plans/openresponses-gateway.md
# docs/zh-CN/experiments/research/memory.md
# docs/zh-CN/gateway/authentication.md
# docs/zh-CN/gateway/background-process.md
# docs/zh-CN/gateway/bonjour.md
# docs/zh-CN/gateway/bridge-protocol.md
# docs/zh-CN/gateway/cli-backends.md
# docs/zh-CN/gateway/configuration-examples.md
# docs/zh-CN/gateway/discovery.md
# docs/zh-CN/gateway/doctor.md
# docs/zh-CN/gateway/gateway-lock.md
# docs/zh-CN/gateway/health.md
# docs/zh-CN/gateway/heartbeat.md
# docs/zh-CN/gateway/index.md
# docs/zh-CN/gateway/local-models.md
# docs/zh-CN/gateway/logging.md
# docs/zh-CN/gateway/multiple-gateways.md
# docs/zh-CN/gateway/openai-http-api.md
# docs/zh-CN/gateway/openresponses-http-api.md
# docs/zh-CN/gateway/pairing.md
# docs/zh-CN/gateway/protocol.md
# docs/zh-CN/gateway/remote-gateway-readme.md
# docs/zh-CN/gateway/remote.md
# docs/zh-CN/gateway/sandbox-vs-tool-policy-vs-elevated.md
# docs/zh-CN/gateway/sandboxing.md
# docs/zh-CN/gateway/security/formal-verification.md
# docs/zh-CN/gateway/security/index.md
# docs/zh-CN/gateway/tailscale.md
# docs/zh-CN/gateway/tools-invoke-http-api.md
# docs/zh-CN/gateway/troubleshooting.md
# docs/zh-CN/help/faq.md
# docs/zh-CN/help/index.md
# docs/zh-CN/help/troubleshooting.md
# docs/zh-CN/hooks.md
# docs/zh-CN/index.md
# docs/zh-CN/install/ansible.md
# docs/zh-CN/install/bun.md
# docs/zh-CN/install/development-channels.md
# docs/zh-CN/install/docker.md
# docs/zh-CN/install/index.md
# docs/zh-CN/install/migrating.md
# docs/zh-CN/install/nix.md
# docs/zh-CN/install/uninstall.md
# docs/zh-CN/install/updating.md
# docs/zh-CN/logging.md
# docs/zh-CN/multi-agent-sandbox-tools.md
# docs/zh-CN/network.md
# docs/zh-CN/nodes/camera.md
# docs/zh-CN/nodes/images.md
# docs/zh-CN/nodes/index.md
# docs/zh-CN/nodes/location-command.md
# docs/zh-CN/nodes/media-understanding.md
# docs/zh-CN/nodes/talk.md
# docs/zh-CN/nodes/voicewake.md
# docs/zh-CN/perplexity.md
# docs/zh-CN/pi-dev.md
# docs/zh-CN/pi.md
# docs/zh-CN/platforms/android.md
# docs/zh-CN/platforms/digitalocean.md
# docs/zh-CN/platforms/exe-dev.md
# docs/zh-CN/platforms/fly.md
# docs/zh-CN/platforms/gcp.md
# docs/zh-CN/platforms/hetzner.md
# docs/zh-CN/platforms/index.md
# docs/zh-CN/platforms/ios.md
# docs/zh-CN/platforms/linux.md
# docs/zh-CN/platforms/mac/bundled-gateway.md
# docs/zh-CN/platforms/mac/canvas.md
# docs/zh-CN/platforms/mac/child-process.md
# docs/zh-CN/platforms/mac/dev-setup.md
# docs/zh-CN/platforms/mac/health.md
# docs/zh-CN/platforms/mac/remote.md
# docs/zh-CN/platforms/mac/skills.md
# docs/zh-CN/platforms/mac/voicewake.md
# docs/zh-CN/platforms/mac/webchat.md
# docs/zh-CN/platforms/mac/xpc.md
# docs/zh-CN/platforms/macos-vm.md
# docs/zh-CN/platforms/macos.md
# docs/zh-CN/platforms/oracle.md
# docs/zh-CN/platforms/raspberry-pi.md
# docs/zh-CN/platforms/windows.md
# docs/zh-CN/plugin.md
# docs/zh-CN/plugins/agent-tools.md
# docs/zh-CN/plugins/voice-call.md
# docs/zh-CN/plugins/zalouser.md
# docs/zh-CN/prose.md
# docs/zh-CN/providers/anthropic.md
# docs/zh-CN/providers/index.md
# docs/zh-CN/providers/minimax.md
# docs/zh-CN/providers/models.md
# docs/zh-CN/providers/qwen.md
# docs/zh-CN/providers/vercel-ai-gateway.md
# docs/zh-CN/refactor/clawnet.md
# docs/zh-CN/refactor/exec-host.md
# docs/zh-CN/refactor/outbound-session-mirroring.md
# docs/zh-CN/refactor/strict-config.md
# docs/zh-CN/reference/AGENTS.default.md
# docs/zh-CN/reference/RELEASING.md
# docs/zh-CN/reference/rpc.md
# docs/zh-CN/reference/session-management-compaction.md
# docs/zh-CN/reference/templates/SOUL.dev.md
# docs/zh-CN/reference/templates/USER.dev.md
# docs/zh-CN/reference/test.md
# docs/zh-CN/security/formal-verification.md
# docs/zh-CN/start/getting-started.md
# docs/zh-CN/start/hubs.md
# docs/zh-CN/start/lore.md
# docs/zh-CN/start/onboarding.md
# docs/zh-CN/start/openclaw.md
# docs/zh-CN/start/pairing.md
# docs/zh-CN/start/setup.md
# docs/zh-CN/start/showcase.md
# docs/zh-CN/start/wizard.md
# docs/zh-CN/testing.md
# docs/zh-CN/token-use.md
# docs/zh-CN/tools/agent-send.md
# docs/zh-CN/tools/browser-linux-troubleshooting.md
# docs/zh-CN/tools/browser-login.md
# docs/zh-CN/tools/browser.md
# docs/zh-CN/tools/chrome-extension.md
# docs/zh-CN/tools/creating-skills.md
# docs/zh-CN/tools/elevated.md
# docs/zh-CN/tools/exec-approvals.md
# docs/zh-CN/tools/exec.md
# docs/zh-CN/tools/firecrawl.md
# docs/zh-CN/tools/index.md
# docs/zh-CN/tools/lobster.md
# docs/zh-CN/tools/skills-config.md
# docs/zh-CN/tools/skills.md
# docs/zh-CN/tools/slash-commands.md
# docs/zh-CN/tools/web.md
# docs/zh-CN/tts.md
# docs/zh-CN/tui.md
# docs/zh-CN/vps.md
# docs/zh-CN/web/control-ui.md
# docs/zh-CN/web/dashboard.md
# docs/zh-CN/web/index.md
# docs/zh-CN/web/webchat.md
* Channels: add Feishu/Lark support
(cherry picked from commit 2483f26c235a2a3271cae733f653ff6d78641726)
# Conflicts:
# docs/docs.json
* fix(approvals): gate /approve by gateway scopes
(cherry picked from commit efe2a464af9fcaa2da13873742003d21408a3f9d)
# Conflicts:
# src/auto-reply/reply/commands-approve.ts
* test: add /approve gateway scope coverage (#1) (thanks @mitsuhiko)
(cherry picked from commit d41acf99a63aafd2259ef716eba407c00f3a0a17)
# Conflicts:
# CHANGELOG.md
* test: reset /approve mock per test (#1) (thanks @mitsuhiko)
(cherry picked from commit 4df4435c45f0292a90d6c0159db46a324f4c1573)
# Conflicts:
# src/auto-reply/reply/commands-approve.test.ts
* chore: prep 2026.2.2 docs/release checks
(cherry picked from commit 539a15e63fcc823256893ccde8bd421db14aba23)
# Conflicts:
# CHANGELOG.md
# scripts/release-check.ts
* chore: update appcast for 2026.2.2
(cherry picked from commit 95cd2210f93d6ab2acc5e29dbad6065294365863)
# Conflicts:
# appcast.xml
* chore: add mac dSYM zip to release artifacts
(cherry picked from commit f1cbe7db1d764e57aea8ec4d8fb1b2a6287fafb5)
# Conflicts:
# scripts/package-mac-dist.sh
* fix(update): honor update.channel for update.run
(cherry picked from commit bbe9cb30224af989782d42d6de8e8053abaee51b)
# Conflicts:
# src/gateway/server-methods/update.ts
# src/infra/update-runner.ts
* feat: add configurable web_fetch maxChars cap
(cherry picked from commit d3ba57b7d7e0c7e9ae26c4b479ce2141c08767e5)
* fix(matrix): require unique allowlist matches in wizard
(cherry picked from commit 41d2993f7bccc43b6046dba20c1bf59dfec6c4b3)
# Conflicts:
# extensions/matrix/src/onboarding.ts
* iMessage: promote BlueBubbles and refresh docs/skills (#8415)
* feat: Make BlueBubbles the primary iMessage integration
- Remove old imsg skill (skills/imsg/SKILL.md)
- Create new BlueBubbles skill (skills/bluebubbles/SKILL.md) with message tool examples
- Add keep-alive script documentation for VM/headless setups to docs/channels/bluebubbles.md
- AppleScript that pokes Messages.app every 5 minutes
- LaunchAgent configuration for automatic execution
- Prevents Messages.app from going idle in VM environments
- Update all documentation to prioritize BlueBubbles over legacy imsg:
- Mark imsg channel as legacy throughout docs
- Update README.md channel lists
- Update wizard, hubs, pairing, and index docs
- Update FAQ to recommend BlueBubbles for iMessage
- Update RPC docs to note imsg as legacy pattern
- Update Chinese documentation (zh-CN)
- Replace imsg examples with generic macOS skill examples where appropriate
BlueBubbles is now the recommended first-class iMessage integration,
with the legacy imsg integration marked for potential future removal.
* refactor: Update import paths and improve code formatting
- Adjusted import paths in session-status-tool.ts, whatsapp-heartbeat.ts, and heartbeat-runner.ts for consistency.
- Reformatted code for better readability by aligning and grouping related imports and function parameters.
- Enhanced error messages and conditional checks for clarity in heartbeat-runner.ts.
* skills: restore imsg skill and align bluebubbles skill
* docs: update FAQ for clarity and formatting
- Adjusted the formatting of the FAQ section to ensure consistent bullet point alignment.
- No content changes were made, only formatting improvements for better readability.
* style: oxfmt touched files
* fix: preserve BlueBubbles developer reference (#8415) (thanks @tyler6204)
(cherry picked from commit 9c4eab69cca597d6ff7a14e652ef069ac06e8b8f)
# Conflicts:
# CHANGELOG.md
# README.md
# docs/help/faq.md
# docs/reference/rpc.md
# skills/bluebubbles/SKILL.md
# src/agents/tools/session-status-tool.ts
# src/channels/plugins/whatsapp-heartbeat.ts
# src/infra/heartbeat-runner.ts
* refactor: remove unnecessary blank line in policy test file
(cherry picked from commit 3e6c623cfea82841eeac3c92ae31481576af7a75)
# Conflicts:
# extensions/nextcloud-talk/src/policy.test.ts
* feat: add new messages indicator style for chat interface
- Introduced a floating pill element above the compose area to indicate new messages.
- Styled the indicator with hover effects and responsive design for better user interaction.
(cherry picked from commit efb4a34be4fdc98e18d928c62442b85edf398404)
* Telegram: add inline button model selection for /models and /model commands
(cherry picked from commit 16349b6e9312a4627fb3e3292511e298487e16ac)
# Conflicts:
# src/auto-reply/reply/commands-models.ts
# src/auto-reply/reply/directive-handling.model.ts
# src/telegram/bot-handlers.ts
* Telegram: fix model button review issues
- Add currentModel to callback handler for checkmark display
- Add 64-byte callback_data limit protection (skip long model IDs)
- Add tests for large model lists and callback_data limits
(cherry picked from commit 202c554d09ad519742be7e928ff66a8ab2cc2b12)
* feat(discord): add set-presence action for bot activity and status
Bridge the agent tools layer to the Discord gateway WebSocket via a new
gateway registry, allowing agents to set the bot's activity and online
status. Supports playing, streaming, listening, watching, custom, and
competing activity types. Custom type uses activityState as the sidebar
text; other types show activityName in the sidebar and activityState in
the flyout. Opt-in via channels.discord.actions.presence (default false).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
(cherry picked from commit 5af322f710be2af011d4fc53de1b39fc77e73ccb)
# Conflicts:
# docs/channels/discord.md
# skills/discord/SKILL.md
# src/discord/monitor/provider.ts
* Address PR feedback
(cherry picked from commit f04e84f194adff236e056acc538cdba5c575844f)
* Make openclaw consistent in this file (#8533)
Co-authored-by: stephenchen2025 <schenjobs@gmail.com>
(cherry picked from commit d2ff28dda7598cbac7e126d655454d8883d76d6d)
# Conflicts:
# src/browser/client-fetch.ts
* feat: add support for Moonshot API key for China endpoint
(cherry picked from commit 1c6b25ddbbeffb51daae43aae85ce01930d9e459)
# Conflicts:
# src/commands/onboard-auth.config-core.ts
* fix(control-ui): resolve header logo when gateway.controlUi.basePath is set (#7178)
* fix(control-ui): resolve header logo when gateway.controlUi.basePath is set
* refactor(control-ui): header logo under basePath; normalize logo URL with normalizeBasePath
(cherry picked from commit 7b3d23b703babb5d6fd9ee6b4e3336c254ed205d)
# Conflicts:
# ui/src/ui/app-render.ts
* Add baidu qianfan model provider
(cherry picked from commit 30ac80b96b452b7f3efcfc447335256c256227a7)
# Conflicts:
# src/cli/program/register.onboard.ts
# src/commands/auth-choice.preferred-provider.ts
# src/commands/onboard-auth.config-core.ts
# src/commands/onboard-auth.ts
* fix(cron): fix timeout, add timestamp validation, enable file sync
Fixes #7667
Task 1: Fix cron operation timeouts
- Increase default gateway tool timeout from 10s to 30s
- Increase cron-specific tool timeout to 60s
- Increase CLI default timeout from 10s to 30s
- Prevents timeouts when gateway is busy with long-running jobs
Task 2: Add timestamp validation
- New validateScheduleTimestamp() function in validate-timestamp.ts
- Rejects atMs timestamps more than 1 minute in the past
- Rejects atMs timestamps more than 10 years in the future
- Applied to both cron.add and cron.update operations
- Provides helpful error messages with current time and offset
Task 3: Enable file sync for manual edits
- Track file modification time (storeFileMtimeMs) in CronServiceState
- Check file mtime in ensureLoaded() and reload if changed
- Recompute next runs after reload to maintain accuracy
- Update mtime after persist() to prevent reload loop
- Dashboard now picks up manual edits to ~/.openclaw/cron/jobs.json
(cherry picked from commit 3a03e38378e2bb9ea17a71cdea5b6b30ae750a3c)
# Conflicts:
# src/cron/service/store.ts
# src/gateway/server-methods/cron.ts
* feat(cron): introduce delivery modes for isolated jobs
- Added support for new delivery modes in cron jobs: `announce`, `deliver`, and `none`.
- Updated documentation to reflect changes in delivery options and usage examples.
- Enhanced the cron job schema to include delivery configuration.
- Refactored related CLI commands and UI components to accommodate the new delivery settings.
- Improved handling of legacy delivery fields for backward compatibility.
This update allows users to choose how output from isolated jobs is delivered, enhancing flexibility in job management.
(cherry picked from commit 511c656cbcb6214b208c5bde44768a16ec388929)
# Conflicts:
# CHANGELOG.md
# docs/automation/cron-jobs.md
# docs/automation/cron-vs-heartbeat.md
# docs/cli/cron.md
# src/cron/isolated-agent/run.ts
* feat(cron): default isolated jobs to announce delivery and enhance scheduling options
- Updated isolated cron jobs to default to `announce` delivery mode, improving user experience.
- Enhanced scheduling options to accept ISO 8601 timestamps for `schedule.at`, while still supporting epoch milliseconds.
- Refined documentation to clarify delivery modes and scheduling formats.
- Adjusted related CLI commands and UI components to reflect these changes, ensuring consistency across the platform.
- Improved handling of legacy delivery fields for backward compatibility.
This update streamlines the configuration of isolated jobs, making it easier for users to manage job outputs and schedules.
(cherry picked from commit 0bb0dfc9bccbab8473a409ae03ab7892920080f9)
# Conflicts:
# CHANGELOG.md
* feat(cron): enhance one-shot job behavior and CLI options
- Default one-shot jobs to delete after success, improving job management.
- Introduced `--keep-after-run` CLI option to allow users to retain one-shot jobs post-execution.
- Updated documentation to clarify default behaviors and new options for one-shot jobs.
- Adjusted cron job creation logic to ensure consistent handling of delete options.
- Enhanced tests to validate new behaviors and ensure reliability.
This update streamlines the handling of one-shot jobs, providing users with more control over job persistence and execution outcomes.
(cherry picked from commit ab9f06f4ffaec25ada17ff6797a33ffb2f6ca07c)
# Conflicts:
# CHANGELOG.md
* feat(cron): enhance delivery modes and job configuration
- Updated isolated cron jobs to support new delivery modes: `announce` and `none`, improving output management.
- Refactored job configuration to remove legacy fields and streamline delivery settings.
- Enhanced the `CronJobEditor` UI to reflect changes in delivery options, including a new segmented control for delivery mode selection.
- Updated documentation to clarify the new delivery configurations and their implications for job execution.
- Improved tests to validate the new delivery behavior and ensure backward compatibility with legacy settings.
This update provides users with greater flexibility in managing how isolated jobs deliver their outputs, enhancing overall usability and clarity in job configurations.
(cherry picked from commit 3f82daefd8010cda5b7ead7c1717a9078acaec29)
# Conflicts:
# CHANGELOG.md
# apps/macos/Sources/Moltbot/CronJobEditor.swift
# docs/zh-CN/automation/cron-vs-heartbeat.md
# src/agents/moltbot-tools.ts
# src/agents/tools/message-tool.ts
# src/cron/isolated-agent/run.ts
# src/cron/service/jobs.ts
* feat(cron): set default enabled state for cron jobs
- Added logic to default the `enabled` property to `true` if not explicitly set as a boolean in the cron job input.
- Updated job creation and store functions to ensure consistent handling of the `enabled` state across the application.
- Enhanced input normalization to improve job configuration reliability.
This update ensures that cron jobs are enabled by default, enhancing user experience and reducing potential misconfigurations.
(cherry picked from commit 140994386388df7c171b25b1cac625d64987430a)
* refactor(cron): update delivery instructions for isolated agent
- Revised the delivery instructions in the isolated agent's command body to clarify that summaries should be returned as plain text and will be delivered by the main agent.
- Removed the previous directive regarding messaging tools to streamline communication guidelines.
This change enhances clarity in the delivery process for isolated agent tasks.
(cherry picked from commit ef4949b936ffc59ce47d03a5526b57f4a62079f8)
* feat(cron): enhance delivery handling and testing for isolated jobs
- Introduced new properties for explicit message targeting and message tool disabling in the EmbeddedRunAttemptParams type.
- Updated cron job tests to validate best-effort delivery behavior and handling of delivery failures.
- Added logic to clear delivery settings when switching session targets in cron jobs.
- Improved the resolution of delivery failures and best-effort logic in the isolated agent's run function.
This update enhances the flexibility and reliability of delivery mechanisms in isolated cron jobs, ensuring better handling of message delivery scenarios.
(cherry picked from commit 64df61f697435a0d359542728b0f03bfba695a67)
* refactor(cron): improve delivery configuration handling in CronJobEditor and CLI
- Enhanced the delivery configuration logic in CronJobEditor to explicitly set the bestEffort property based on job settings.
- Refactored the CLI command to streamline delivery object creation, ensuring proper handling of optional fields like channel and to.
- Improved code readability and maintainability by restructuring delivery assignment logic.
This update clarifies the delivery configuration process, enhancing the reliability of job settings in both the editor and CLI.
(cherry picked from commit 246896d64bf4025cd2d9e13b1911c28079fd6209)
* feat(cron): enhance legacy delivery handling in job patches
- Introduced logic to map legacy payload delivery updates onto the delivery object for `agentTurn` jobs, ensuring backward compatibility with legacy clients.
- Added tests to validate the correct application of legacy delivery settings in job patches, improving reliability in job configuration.
- Refactored delivery handling functions to streamline the merging of legacy delivery fields into the current job structure.
This update enhances the flexibility of delivery configurations, ensuring that legacy settings are properly handled in the context of new job patches.
(cherry picked from commit 6fb8d8850e952a61f13947f2c41fc28b0603f039)
* fix(cron): fix test failures and regenerate protocol files
- Add forceReload option to ensureLoaded to avoid stat I/O in normal
paths while still detecting cross-service writes in the timer path
- Post isolated job summary back to main session (restores the old
isolation.postToMainPrefix behavior via delivery model)
- Update legacy migration tests to check delivery.channel instead of
payload.channel (normalization now moves delivery fields to top-level)
- Remove legacy deliver/channel/to/bestEffortDeliver from payload schema
- Update protocol conformance test for delivery modes
- Regenerate GatewayModels.swift (isolation -> delivery)
(cherry picked from commit f8d253406296a548e53a63651834b8b9cb1fb405)
# Conflicts:
# src/cron/cron-protocol-conformance.test.ts
* UI: handle future timestamps in formatAgo
(cherry picked from commit 79d00e20db8d5c9a8b30dfb0c835b4e895c6f6fb)
# Conflicts:
# ui/src/ui/format.test.ts
* Telegram: use Grammy types directly, add typed Probe/Audit to plugin interface (#8403)
* Telegram: replace duplicated types with Grammy imports, add Probe/Audit generics to plugin interface
* Telegram: remove legacy forward metadata (deprecated in Bot API 7.0), simplify required-field checks
* Telegram: clean up remaining legacy references and unnecessary casts
* Telegram: keep RequestInit parameter type in proxy fetch (addresses review feedback)
* Telegram: add exhaustiveness guard to resolveForwardOrigin switch
(cherry picked from commit da6de4981557d42c13af8a93706c07eb6231e7a5)
# Conflicts:
# extensions/telegram/src/channel.ts
# src/channels/plugins/types.adapters.ts
# src/telegram/bot-native-commands.ts
# src/telegram/bot-updates.ts
# src/telegram/bot.ts
# src/telegram/bot/helpers.test.ts
# src/telegram/bot/helpers.ts
* fix(telegram): include forward_from_chat metadata in forwarded message context (#8133)
Extract missing metadata from forwarded Telegram messages:
- Add fromChatType to TelegramForwardedContext, capturing the original
chat type (channel/supergroup/group) from forward_from_chat.type
and forward_origin.chat/sender_chat.type
- Add fromMessageId to capture the original message ID from channel forwards
- Read author_signature from forward_origin objects (modern API),
preferring it over the deprecated forward_signature field
- Pass ForwardedFromChatType and ForwardedFromMessageId through to
the inbound context payload
- Add test coverage for forward_origin channel/chat types, including
author_signature extraction and fromChatType propagation
(cherry picked from commit 57566c5e4d633ce199fc24901580fc5ffa9b1350)
# Conflicts:
# src/telegram/bot/helpers.test.ts
* fix(imessage): unify timeout configuration with configurable probeTimeoutMs
- Add probeTimeoutMs config option to channels.imessage
- Export DEFAULT_IMESSAGE_PROBE_TIMEOUT_MS constant (10s) from probe.ts
- Propagate timeout config through all iMessage probe/RPC operations
- Fix hardcoded 2000ms timeouts that were too short for SSH connections
Closes: timeout issues when using SSH wrapper scripts (imsg-ssh)
(cherry picked from commit 78f8a29071305db4b060911aded4d787e69e2ac0)
* fix(imessage): detect self-chat echoes to prevent infinite loops (#8680)
(cherry picked from commit 18652d181b47732c7389391da56e7536656e5cf4)
* feat: add cloudflare ai gateway provider
(cherry picked from commit 5b0851ebd82cd7ec3372d070ab4d73fda81bd959)
# Conflicts:
# CHANGELOG.md
# README.md
# src/agents/models-config.providers.ts
# src/cli/program/register.onboard.ts
# src/commands/auth-choice.apply.api-providers.ts
# src/commands/onboard-auth.config-core.ts
# src/commands/onboard-auth.ts
# src/commands/onboard-non-interactive/local/auth-choice.ts
* Fix format
(cherry picked from commit 7bf408060885257e17d77b0674cb39c241e81da9)
# Conflicts:
# docs/docs.json
* optimize doc
(cherry picked from commit fb5280e1b5cd0315390f95b3100759020f683ee5)
# Conflicts:
# docs/providers/qianfan.md
* Docs: landing page revamp (#8885)
* Docs: refresh landing page
* Docs: add landing page companion pages
* Docs: drop legacy Jekyll assets
* Docs: remove legacy terminal css test
* Docs: restore terminal css assets
* Docs: remove terminal css assets
(cherry picked from commit 718dba8cb69201e3163a62a3542a9777e4df0538)
# Conflicts:
# docs/_config.yml
# docs/_layouts/default.html
# docs/assets/theme.js
# docs/docs.json
# docs/index.md
* fix(app-render): handle optional model in renderApp function
(cherry picked from commit 01ce144fa9abf8dc920d476e0f420a33356a8e41)
# Conflicts:
# ui/src/ui/app-render.ts
* feat: add shell completion installation prompt to CLI update command
(cherry picked from commit 1d17630dc654a0f27aeba65484e6769434bf38fa)
# Conflicts:
# src/cli/update-cli.ts
* feat: add shell completion test script for installation verification
(cherry picked from commit 42c690632d792f8c5fe48c089979f977b4454dd9)
* completion: export cache utilities and require cached file for installation
- Export `resolveCompletionCachePath` and `completionCacheExists` for external use
- Update `installCompletion` to require cache existence (never use slow dynamic pattern)
- Add `usesSlowDynamicCompletion` to detect old `source <(...)` patterns
- Add `getShellProfilePath` helper for consistent profile path resolution
- Update `formatCompletionSourceLine` to always use cached file
(cherry picked from commit d5f8208c38793eab899cb9a76bc5d85d257c12c8)
* doctor: add shell completion check module
- Add `checkShellCompletionStatus` to get profile/cache/slow-pattern status
- Add `ensureCompletionCacheExists` for silent cache regeneration
- Add `doctorShellCompletion` to check and fix completion issues:
- Auto-upgrade old slow dynamic patterns to cached version
- Auto-regenerate cache if profile exists but cache is missing
- Prompt to install if no completion is configured
(cherry picked from commit 3fae90386328a264916e92c55dcf71a29c9350f7)
* doctor: integrate shell completion check into doctor command
- Import and call `doctorShellCompletion` during doctor run
- Checks/fixes completion issues before gateway health check
(cherry picked from commit 5bd63b012c9c617edbcb9c5e5ab62a5e690661c9)
* update: use shared completion helpers for shell completion setup
- Replace inline completion logic with `checkShellCompletionStatus` and `ensureCompletionCacheExists`
- Auto-upgrade old slow dynamic patterns silently during update
- Auto-regenerate cache if profile exists but cache is missing
- Prompt to install if no completion is configured
(cherry picked from commit dbaf0a8ae27cb8a75d21b391e20378a0a1f5d1d7)
# Conflicts:
# src/cli/update-cli.ts
* onboard: use shared completion helpers for shell completion setup
- Replace inline completion logic with `checkShellCompletionStatus` and `ensureCompletionCacheExists`
- Auto-upgrade old slow dynamic patterns silently during onboarding
- Auto-regenerate cache if profile exists but cache is missing
- Prompt to install if no completion is configured
(cherry picked from commit 3e14192730b128a47795c2f8246a13726fb32953)
# Conflicts:
# src/wizard/onboarding.finalize.ts
* scripts: update test-shell-completion to use shared helpers
- Use `checkShellCompletionStatus` and `ensureCompletionCacheExists` from doctor-completion
- Display "Uses slow pattern" status in output
- Simulate doctor/update/onboard behavior for all completion scenarios
- Remove duplicated utility functions
(cherry picked from commit dae0e2b3258d4e259d12df52d80339846a790f61)
* feat: per-channel responsePrefix override (#9001)
* feat: per-channel responsePrefix override
Add responsePrefix field to all channel config types and Zod schemas,
enabling per-channel and per-account outbound response prefix overrides.
Resolution cascade (most specific wins):
L1: channels.<ch>.accounts.<id>.responsePrefix
L2: channels.<ch>.responsePrefix
L3: (reserved for channels.defaults)
L4: messages.responsePrefix (existing global)
Semantics:
- undefined -> inherit from parent level
- empty string -> explicitly no prefix (stops cascade)
- "auto" -> derive [identity.name] from routed agent
Changes:
- Core logic: resolveResponsePrefix() in identity.ts accepts
optional channel/accountId and walks the cascade
- resolveEffectiveMessagesConfig() passes channel context through
- Types: responsePrefix added to WhatsApp, Telegram, Discord, Slack,
Signal, iMessage, Google Chat, MS Teams, Feishu, BlueBubbles configs
- Zod schemas: responsePrefix added for config validation
- All channel handlers wired: telegram, discord, slack, signal,
imessage, line, heartbeat runner, route-reply, native commands
- 23 new tests covering backward compat, channel/account levels,
full cascade, auto keyword, empty string stops, unknown fallthrough
Fully backward compatible - no existing config is affected.
Fixes #8857
* fix: address CI lint + review feedback
- Replace Record<string, any> with proper typed helpers (no-explicit-any)
- Add curly braces to single-line if returns (eslint curly)
- Fix JSDoc: 'Per-channel' → 'channel/account' on shared config types
- Extract getChannelConfig() helper for type-safe dynamic key access
* fix: finish responsePrefix overrides (#9001) (thanks @mudrii)
* fix: normalize prefix wiring and types (#9001) (thanks @mudrii)
---------
Co-authored-by: Gustavo Madeira Santana <gumadeiras@gmail.com>
(cherry picked from commit 5d82c82313a1f305bea5a3cd14847a35e93c589b)
# Conflicts:
# CHANGELOG.md
# extensions/bluebubbles/src/monitor.ts
# extensions/googlechat/src/monitor.ts
# extensions/tlon/src/monitor/index.ts
# extensions/twitch/src/monitor.ts
# extensions/zalo/src/monitor.ts
# extensions/zalouser/src/monitor.ts
# src/agents/identity.ts
# src/auto-reply/reply/route-reply.ts
# src/discord/monitor/message-handler.process.ts
# src/discord/monitor/native-command.ts
# src/feishu/message.ts
# src/gateway/server-methods/chat.ts
# src/line/monitor.ts
# src/slack/monitor/slash.ts
# src/telegram/bot-message-dispatch.test.ts
# src/telegram/bot-message-dispatch.ts
# src/telegram/bot-native-commands.ts
# src/web/auto-reply/monitor/process-message.ts
* Discord: allow disabling thread starter context
(cherry picked from commit bebf3237756344221a1ed5a0960d01b375572050)
* feat(heartbeat): add accountId config option for multi-agent routing (#8702)
* feat(heartbeat): add accountId config option for multi-agent routing
Add optional accountId field to heartbeat configuration, allowing
multi-agent setups to explicitly specify which Telegram account
should be used for heartbeat delivery.
Previously, heartbeat delivery would use the accountId from the
session's deliveryContext. When a session had no prior conversation
history, heartbeats would default to the first/primary account
instead of the agent's intended bot.
Changes:
- Add accountId to HeartbeatSchema (zod-schema.agent-runtime.ts)
- Use heartbeat.accountId with fallback to session accountId (targets.ts)
Backward compatible: if accountId is not specified, behavior is unchanged.
Closes #8695
* fix: improve heartbeat accountId routing (#8702) (thanks @lsh411)
* fix: harden heartbeat accountId routing (#8702) (thanks @lsh411)
* fix: expose heartbeat accountId in status (#8702) (thanks @lsh411)
* chore: format status + heartbeat tests (#8702) (thanks @lsh411)
---------
Co-authored-by: m1 16 512 <m116512@m1ui-MacBookAir-2.local>
Co-authored-by: Gustavo Madeira Santana <gumadeiras@gmail.com>
(cherry picked from commit a42e3cb78ab75233a5ebcc949d2532630ec234c5)
# Conflicts:
# CHANGELOG.md
# src/commands/status.command.ts
# src/infra/heartbeat-runner.returns-default-unset.test.ts
# src/infra/outbound/targets.ts
* Telegram: remove @ts-nocheck from bot.ts, fix duplicate error handler, harden sticker caching (#9077)
* Telegram: remove @ts-nocheck from bot.ts and bot-message-dispatch.ts
- bot/types.ts: TelegramContext.me uses UserFromGetMe (Grammy) instead of manual inline type
- bot.ts: remove 6 unsafe casts (as any, as unknown, as object), use Grammy types directly
- bot.ts: remove dead message_thread_id access on reactions (not in Telegram Bot API)
- bot.ts: remove resolveThreadSessionKeys import (no longer needed for reactions)
- bot-message-dispatch.ts: replace ': any' with DispatchTelegramMessageParams type
- bot-message-dispatch.ts: add sticker.fileId guard before cache access
- bot.test.ts: update reaction tests, remove dead DM thread-reaction test
* Telegram: remove duplicate bot.catch handler (only the last one runs in Grammy)
* Telegram: remove @ts-nocheck from bot.ts, fix duplicate error handler, harden sticker caching (#9077)
(cherry picked from commit 96abc1c864376689abb76a1c49a7443390ab6749)
# Conflicts:
# src/telegram/bot.ts
* Tests: restore TUI gateway env
(cherry picked from commit 5e025c4ba3412b142dd326f900ca66a354c186ff)
# Conflicts:
# src/tui/gateway-chat.test.ts
* Telegram: remove @ts-nocheck from bot-message.ts (#9180)
* Telegram: remove @ts-nocheck from bot-message.ts, type deps via Omit<BuildTelegramMessageContextParams>
* Telegram: widen allMedia to TelegramMediaRef[] so stickerMetadata flows through
* Telegram: remove @ts-nocheck from bot-message.ts (#9180)
(cherry picked from commit 90b4e54354741d062059afb13f7c43a6ae8640ef)
* Telegram: remove last @ts-nocheck from bot-handlers.ts (#9206)
* Telegram: remove @ts-nocheck from bot-handlers.ts, use Grammy types directly, deduplicate StickerMetadata
* Telegram: remove last @ts-nocheck from bot-handlers.ts (#9206)
(cherry picked from commit 21f8c3db18f1fc445b96a9a72e2ec74e049afa1a)
# Conflicts:
# src/telegram/bot-message-context.ts
* Message: clarify media schema + fix MEDIA newline
(cherry picked from commit a6fd76efebd3171d7f575e7ae298b60fdb3ef897)
# Conflicts:
# src/infra/outbound/message-action-runner.test.ts
* fix(mac): resolve cron schedule formatters
(cherry picked from commit cfdc551346b674b4a6f8714e634b37f95ed7d1be)
* chore(mac): update appcast for 2026.2.3
(cherry picked from commit 7f95cdac78fef994b53f888e08a0681d5e4c9c75)
# Conflicts:
# appcast.xml
* Fix import error
(cherry picked from commit c8e67ad5d576ce26bd62041d062daa226a554887)
# Conflicts:
# src/commands/onboard-auth.config-core.ts
* Add auth choice
(cherry picked from commit 52c9d3480fb4d949e7f471fb8c1a7def1398d5a7)
* Fix key resolve
(cherry picked from commit 4d30f97407a75168a9d7e7683ad2158ee3b3d22c)
* Optimize import
(cherry picked from commit 7af00f040aa055e9a9278e29085d0dcb092e7ae7)
# Conflicts:
# src/cron/isolated-agent/run.ts
* fix(cli): resolve bundled chrome extension path
(cherry picked from commit 0621d0e9e82d62170db3c54f6852200b99ec1188)
# Conflicts:
# src/cli/browser-cli-extension.test.ts
* test(cli): use unique temp dir for extension install
(cherry picked from commit 1008c28f5a65d706bf7c0892fb4b5d76d729ff04)
# Conflicts:
# src/cli/browser-cli-extension.test.ts
* fix(cli): support…
…interface (openclaw#8403) * Telegram: replace duplicated types with Grammy imports, add Probe/Audit generics to plugin interface * Telegram: remove legacy forward metadata (deprecated in Bot API 7.0), simplify required-field checks * Telegram: clean up remaining legacy references and unnecessary casts * Telegram: keep RequestInit parameter type in proxy fetch (addresses review feedback) * Telegram: add exhaustiveness guard to resolveForwardOrigin switch
Summary
Replaces duplicated Telegram API type definitions with imports from
@grammyjs/typesand addsProbe/Audittype parameters to the channel plugin interface so probe results flow type-safely through the status pipeline.Changes
src/telegram/bot/types.ts— deleted 10 duplicated types (TelegramMessage,TelegramQuote,TelegramLocation,TelegramVenue,TelegramForwardUser,TelegramForwardChat,TelegramForwardOrigin,TelegramForwardMetadata,TelegramForwardedMessage,TelegramForwardOriginType), replaced with Grammy imports (Message,User,Chat). Kept app-specific types:TelegramContext,TelegramStreamMode,StickerMetadata.src/telegram/bot/helpers.ts— removed legacyforward_from/forward_from_chat/forward_sender_namefallback paths fromnormalizeForwardedContext(). These fields were replaced byforward_originin Telegram Bot API 7.0 (Dec 2023) and removed from Grammy types in@grammyjs/types@3.4.0. The core forwarding feature from #1090 (thanks @sleontenko) is unchanged —normalizeForwardedContext(),resolveForwardOrigin(), and all the label/context builders remain; only the unreachable legacy fallback branches and their tests were removed. Also simplifiednormalizeForwardedUserLabel/normalizeForwardedChatLabelto reflect that Grammy'sUser.idandChat.idare required fields (no null checks needed). SwitchedresolveForwardOriginto aswitchon the discriminatedMessageOriginunion for proper narrowing.src/channels/plugins/types.adapters.ts+types.plugin.ts— addedProbe = unknownandAudit = unknowntype parameters toChannelStatusAdapterandChannelPlugin. Existing channels are unaffected (defaults tounknown). Channels can opt in for type-safe probe/audit flow.extensions/telegram/src/channel.ts— usesChannelPlugin<ResolvedTelegramAccount, TelegramProbe>, eliminating 3 unsafeascasts on probe access and 2 unnecessaryascasts on already-typed group config.src/telegram/proxy.ts— removed@ts-nocheck, singleas unknown as typeof fetchcast at the undici/global fetch boundary.Consumer files (
bot.ts,bot-handlers.ts,bot-updates.ts,bot-native-commands.ts,helpers.ts) — importMessagefrom@grammyjs/typesinstead of the deletedTelegramMessage.Type boundary
Testing
pnpm checkpasses (tsc + lint + format)Greptile Overview
Greptile Summary
This PR modernizes Telegram integration types by removing local duplicated Bot API shapes and importing canonical types from
@grammyjs/types(e.g.Message,User,Chat,MessageOrigin). It also simplifies forwarding normalization to rely exclusively onforward_origin(Bot API 7.0+) and updates related tests accordingly.On the channel/plugin side, it adds optional
Probe/Auditgenerics toChannelStatusAdapterandChannelPluginso status probe/audit results can flow through the pipeline with type safety; the Telegram extension opts in viaChannelPlugin<ResolvedTelegramAccount, TelegramProbe>, eliminating several unsafe casts.One area to double-check is the proxy fetch wrapper: the new boundary cast is fine, but the wrapper’s parameter typing/spread could subtly change
RequestInithandling if non-plain objects are passed through.Confidence Score: 4/5
unknown), which should be source-compatible. Forwarding normalization intentionally drops legacy fields in line with Bot API 7.0. The main risk is a subtle runtime behavior change inmakeProxyFetchdue to narrowing/spreadinginitas a plain record instead ofRequestInit.(4/5) You can add custom instructions or style guidelines for the agent here!