fix(doctor): suppress repeated legacy state migration warnings#11709
fix(doctor): suppress repeated legacy state migration warnings#11709gumadeiras merged 3 commits intomainfrom
Conversation
src/infra/state-migrations.ts
Outdated
| function isLegacyTreeSymlinkMirror(currentDir: string, targetDir: string): boolean { | ||
| let entries: fs.Dirent[]; | ||
| try { |
There was a problem hiding this comment.
Empty dir treated mirrored
isLegacyTreeSymlinkMirror() returns true when currentDir is empty (because the for loop doesn’t run and it falls through to return true at src/infra/state-migrations.ts:403). That makes autoMigrateLegacyStateDir() suppress the target already exists warning for an empty legacy dir (i.e., not actually a symlink mirror). This will hide a real conflict/no-op situation where the user likely needs to merge/remove manually.
Also appears at src/infra/state-migrations.ts:492-495 (early-return on “mirror”).
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/infra/state-migrations.ts
Line: 368:370
Comment:
**Empty dir treated mirrored**
`isLegacyTreeSymlinkMirror()` returns `true` when `currentDir` is empty (because the `for` loop doesn’t run and it falls through to `return true` at `src/infra/state-migrations.ts:403`). That makes `autoMigrateLegacyStateDir()` suppress the `target already exists` warning for an empty legacy dir (i.e., not actually a symlink mirror). This will hide a real conflict/no-op situation where the user likely needs to merge/remove manually.
Also appears at `src/infra/state-migrations.ts:492-495` (early-return on “mirror”).
How can I resolve this? If you propose a fix, please make it concise.| it("does not warn when legacy state dir is an already-migrated symlink mirror", async () => { | ||
| const root = await makeTempRoot(); | ||
| const targetDir = path.join(root, ".openclaw"); | ||
| const legacyDir = path.join(root, ".moltbot"); | ||
| fs.mkdirSync(path.join(targetDir, "sessions"), { recursive: true }); | ||
| fs.mkdirSync(path.join(targetDir, "agent"), { recursive: true }); | ||
| fs.mkdirSync(legacyDir, { recursive: true }); | ||
|
|
||
| const dirLinkType = process.platform === "win32" ? "junction" : "dir"; | ||
| fs.symlinkSync(path.join(targetDir, "sessions"), path.join(legacyDir, "sessions"), dirLinkType); | ||
| fs.symlinkSync(path.join(targetDir, "agent"), path.join(legacyDir, "agent"), dirLinkType); | ||
|
|
||
| const result = await autoMigrateLegacyStateDir({ | ||
| env: {} as NodeJS.ProcessEnv, | ||
| homedir: () => root, | ||
| }); | ||
|
|
||
| expect(result.migrated).toBe(false); | ||
| expect(result.warnings).toEqual([]); | ||
| }); |
There was a problem hiding this comment.
Missing empty-legacy case
Given the new mirror suppression path, an empty legacy dir with an existing target dir will currently be treated as a “symlink mirror” (no entries ⇒ isLegacyTreeSymlinkMirror() returns true) and will suppress the warning. There should be a test asserting that an empty legacy directory still warns when targetDir already exists, to prevent the mirror heuristic from silencing real conflicts.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/commands/doctor-state-migrations.test.ts
Line: 356:375
Comment:
**Missing empty-legacy case**
Given the new mirror suppression path, an empty legacy dir with an existing target dir will currently be treated as a “symlink mirror” (no entries ⇒ `isLegacyTreeSymlinkMirror()` returns true) and will suppress the warning. There should be a test asserting that an empty legacy directory still warns when `targetDir` already exists, to prevent the mirror heuristic from silencing real conflicts.
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
Pull request overview
Suppresses repeated “target already exists” warnings during legacy state dir auto-migration when the legacy directory is already effectively redirected into the new ~/.openclaw tree via a symlink-mirror layout, while preserving warnings for genuine conflicts.
Changes:
- Add filesystem-based detection for legacy directories that are symlink mirrors of the new state tree and suppress the warning in that case.
- Add test coverage for symlink-mirror, nested mirror, non-symlink conflict, and “symlink points outside” scenarios.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
src/infra/state-migrations.ts |
Adds symlink-mirror detection and uses it to suppress repeated “target already exists” warnings. |
src/commands/doctor-state-migrations.test.ts |
Adds tests covering the new suppression behavior and conflict cases. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| } | ||
| if (!isWithinDir(resolvedTarget, targetDir)) { | ||
| return false; | ||
| } |
There was a problem hiding this comment.
isLegacyTreeSymlinkMirror() doesn’t verify that a symlink’s resolved target actually exists. A broken symlink whose textual target happens to be under targetDir will be treated as a valid mirror and will suppress the warning, even though state reads via the legacy path may still fail. Consider checking fs.existsSync/statSync for resolvedTarget (and failing closed on errors) before treating it as mirrored.
| } | |
| } | |
| try { | |
| // Ensure the symlink target actually exists; fail closed on any error. | |
| fs.statSync(resolvedTarget); | |
| } catch { | |
| return false; | |
| } |
src/infra/state-migrations.ts
Outdated
| function isLegacyTreeSymlinkMirror(currentDir: string, targetDir: string): boolean { | ||
| let entries: fs.Dirent[]; | ||
| try { | ||
| entries = fs.readdirSync(currentDir, { withFileTypes: true }); | ||
| } catch { | ||
| return false; | ||
| } | ||
|
|
||
| for (const entry of entries) { | ||
| const entryPath = path.join(currentDir, entry.name); | ||
| let stat: fs.Stats; | ||
| try { | ||
| stat = fs.lstatSync(entryPath); | ||
| } catch { | ||
| return false; | ||
| } | ||
| if (stat.isSymbolicLink()) { | ||
| const resolvedTarget = resolveSymlinkTarget(entryPath); | ||
| if (!resolvedTarget) { | ||
| return false; | ||
| } | ||
| if (!isWithinDir(resolvedTarget, targetDir)) { | ||
| return false; | ||
| } | ||
| continue; | ||
| } | ||
| if (stat.isDirectory()) { | ||
| if (!isLegacyTreeSymlinkMirror(entryPath, targetDir)) { | ||
| return false; | ||
| } | ||
| continue; | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| return true; |
There was a problem hiding this comment.
isLegacyTreeSymlinkMirror() currently treats an empty directory (or a directory tree containing only empty directories) as a valid “symlink mirror” because it returns true when readdirSync() yields zero entries. This can suppress the "target already exists" warning even when the legacy dir isn’t actually a symlink mirror (it may just be an empty leftover directory). Consider requiring at least one symlink somewhere in the traversed tree (or special-case the top-level legacy dir) before returning true so the suppression only triggers for the intended already-migrated mirror layout.
| if (stat.isSymbolicLink()) { | ||
| const resolvedTarget = resolveSymlinkTarget(entryPath); | ||
| if (!resolvedTarget) { | ||
| return false; | ||
| } | ||
| if (!isWithinDir(resolvedTarget, targetDir)) { | ||
| return false; | ||
| } |
There was a problem hiding this comment.
The “symlinks escaping the target tree” check only verifies the immediate readlinkSync() target path string is within targetDir. This can still allow escapes if the resolved target itself is (or contains) a symlink/junction that points outside the tree (e.g., legacy entry -> ${targetDir}/link, where ${targetDir}/link is a symlink to /outside). To match the intended safety property, consider validating against realpathSync (fail closed on errors) for both the target and targetDir, and/or ensuring the final resolved real path stays within the real path of targetDir.
|
Merged via squash.
Thanks @gumadeiras! |
Sync main branch updates including: - fix(doctor): suppress repeated legacy state migration warnings (openclaw#11709) - feat(telegram): add spoiler tag support (openclaw#11543) - fix(discord): support forum channel thread-create (openclaw#10062) - fix(ui): smooth chat refresh scroll and suppress new-messages badge flash - fix: context overflow compaction and subagent announce improvements (openclaw#11664) - fix(cron): share isolated announce flow + harden cron scheduling/delivery (openclaw#11641) Conflicts resolved: - CHANGELOG.md (merged both sets of changes) - src/agents/pi-embedded-runner/run.ts (kept tool result truncation logic)
…law#11709) * fix(doctor): suppress repeated state migration warning * fix: harden state-dir mirror detection + warnings (openclaw#11709) (thanks @gumadeiras) * test: cover mirror hardening edge cases (openclaw#11709) (thanks @gumadeiras) (cherry picked from commit b75d618) # Conflicts: # CHANGELOG.md
* Add baidu qianfan model provider * Add baidu qianfan model provider * Fix format * Optimize doc * optimize doc * Fix import error * Add auth choice * Optimize format * Optimize doc * Fix key resolve * Optimize import * Support ERNIE-5.0-Thinking-Preview * Resolve conflicts * Fix conflicts * Docs: add PR sign-off template (openclaw#10561) * fix: guard resolveUserPath against undefined input (openclaw#10176) * fix: guard resolveUserPath against undefined input When subagent spawner omits workspaceDir, resolveUserPath receives undefined and crashes on .trim(). Add a falsy guard that falls back to process.cwd(), matching the behavior callers already expect. Closes openclaw#10089 Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: harden runner workspace fallback (openclaw#10176) (thanks @Yida-Dev) * fix: harden workspace fallback scoping (openclaw#10176) (thanks @Yida-Dev) * refactor: centralize workspace fallback classification and redaction (openclaw#10176) (thanks @Yida-Dev) * test: remove explicit any from utils mock (openclaw#10176) (thanks @Yida-Dev) * security: reject malformed agent session keys for workspace resolution (openclaw#10176) (thanks @Yida-Dev) --------- Co-authored-by: Yida-Dev <[email protected]> Co-authored-by: Claude Opus 4.6 <[email protected]> Co-authored-by: Gustavo Madeira Santana <[email protected]> * Docs: revise PR and issue submission guides (openclaw#10617) * Docs: revise PR submission guide * Docs: revise issue submission guide * feat(memory): native Voyage AI support (openclaw#7078) * feat(memory): add native Voyage AI embedding support with batching Cherry-picked from PR openclaw#2519, resolved conflict in memory-search.ts (hasRemote -> hasRemoteConfig rename + added voyage provider) * fix(memory): optimize voyage batch memory usage with streaming and deduplicate code Cherry-picked from PR openclaw#2519. Fixed lint error: changed this.runWithConcurrency to use imported runWithConcurrency function after extraction to internal.ts * feat(memory): document Voyage embeddings + VOYAGE_API_KEY (openclaw#7078) (thanks @mcinteerj) (openclaw#10699) * feat(antigravity): update default model to Claude Opus 4.6 (openclaw#10720) * feat(antigravity): update default model to Claude Opus 4.6 Claude Opus 4.5 has been replaced by Claude Opus 4.6 on the Antigravity (Google Cloud Code Assist) platform. - Update DEFAULT_MODEL in google-antigravity-auth extension - Update testing docs to reference the new model * fix: update remaining antigravity opus 4.5 refs in zh-CN docs and tests Address review comments from Greptile: - Update zh-CN/testing.md antigravity model references - Update pi-tools-agent-config.test.ts model IDs * Antigravity: default OAuth model to Opus 4.6 (openclaw#10720) (thanks @calvin-hpnet) --------- Co-authored-by: Tak Hoffman <[email protected]> * fix(hooks): replace debug console.log with proper subsystem logging in session-memory (openclaw#10730) * fix: replace debug console.log with proper subsystem logging in session-memory * fix(hooks): normalize session-memory subsystem logging --------- Co-authored-by: Tak Hoffman <[email protected]> * docs(changelog): prepare 2026.2.6 * docs(changelog): include merged PRs since v2026.2.3 * chore(release): bump version to 2026.2.6 * fix(telegram): cast fetch for grammY ApiClientOptions * docs: fix markdownlint fragments + headings * docs(changelog): refresh 2026.2.6 since v2026.2.3 * docs(imessage): add macOS TCC troubleshooting * docs(imessage): improve macOS TCC troubleshooting guidance (openclaw#10781) * chore(deps): update deps * fix(agents): add Opus 4.6 forward-compat fallback * chore(deps): bump carbon beta * docs(changelog): curate 2026.2.6 * docs(changelog): highlight Opus 4.6 + Codex 5.3 first * Fix QMD CLI installation link in memory.md (openclaw#8647) Correct the installation link for the QMD CLI in the documentation. * chore(lockfile): fix pnpm-lock * fix: cron scheduler reliability, store hardening, and UX improvements (openclaw#10776) * refactor: update cron job wake mode and run mode handling - Changed default wake mode from 'next-heartbeat' to 'now' in CronJobEditor and related CLI commands. - Updated cron-tool tests to reflect changes in run mode, introducing 'due' and 'force' options. - Enhanced cron-tool logic to handle new run modes and ensure compatibility with existing job structures. - Added new tests for delivery plan consistency and job execution behavior under various conditions. - Improved normalization functions to handle wake mode and session target casing. This refactor aims to streamline cron job configurations and enhance the overall user experience with clearer defaults and improved functionality. * test: enhance cron job functionality and UI - Added tests to ensure the isolated agent correctly announces the final payload text when delivering messages via Telegram. - Implemented a new function to pick the last deliverable payload from a list of delivery payloads. - Enhanced the cron service to maintain legacy "every" jobs while minute cron jobs recompute schedules. - Updated the cron store migration tests to verify the addition of anchorMs to legacy every schedules. - Improved the UI for displaying cron job details, including job state and delivery information, with new styles and layout adjustments. These changes aim to improve the reliability and user experience of the cron job system. * test: enhance sessions thinking level handling - Added tests to verify that the correct thinking levels are applied during session spawning. - Updated the sessions-spawn-tool to include a new parameter for overriding thinking levels. - Enhanced the UI to support additional thinking levels, including "xhigh" and "full", and improved the handling of current options in dropdowns. These changes aim to improve the flexibility and accuracy of thinking level configurations in session management. * feat: enhance session management and cron job functionality - Introduced passthrough arguments in the test-parallel script to allow for flexible command-line options. - Updated session handling to hide cron run alias session keys from the sessions list, improving clarity. - Enhanced the cron service to accurately record job start times and durations, ensuring better tracking of job execution. - Added tests to verify the correct behavior of the cron service under various conditions, including zero-delay timers. These changes aim to improve the usability and reliability of session and cron job management. * feat: implement job running state checks in cron service - Added functionality to prevent manual job runs if a job is already in progress, enhancing job management. - Updated the `isJobDue` function to include checks for running jobs, ensuring accurate scheduling. - Enhanced the `run` function to return a specific reason when a job is already running. - Introduced a new test case to verify the behavior of forced manual runs during active job execution. These changes aim to improve the reliability and clarity of cron job execution and management. * feat: add session ID and key to CronRunLogEntry model - Introduced `sessionid` and `sessionkey` properties to the `CronRunLogEntry` struct for enhanced tracking of session-related information. - Updated the initializer and Codable conformance to accommodate the new properties, ensuring proper serialization and deserialization. These changes aim to improve the granularity of logging and session management within the cron job system. * fix: improve session display name resolution - Updated the `resolveSessionDisplayName` function to ensure that both label and displayName are trimmed and default to an empty string if not present. - Enhanced the logic to prevent returning the key if it matches the label or displayName, improving clarity in session naming. These changes aim to enhance the accuracy and usability of session display names in the UI. * perf: skip cron store persist when idle timer tick produces no changes recomputeNextRuns now returns a boolean indicating whether any job state was mutated. The idle path in onTimer only persists when the return value is true, eliminating unnecessary file writes every 60s for far-future or idle schedules. * fix: prep for merge - explicit delivery mode migration, docs + changelog (openclaw#10776) (thanks @tyler6204) * Docs: fix broken /plugins links (openclaw#9308) * Docs: fix broken /plugins links to /plugin The documentation linked to /plugins which doesn't exist. The correct path is /plugin (singular) which contains the plugins overview documentation. Co-Authored-By: Claude Opus 4.5 <[email protected]> * docs: drop manual zh-CN doc edits from plugins link fix --------- Co-authored-by: Claude Opus 4.5 <[email protected]> Co-authored-by: Sebastian <[email protected]> * fix(build): unblock pnpm build dts * Fix repository links in formal-verification.md (openclaw#10200) Updated repository links for formal verification models. * Revert previous change from 'Clawdbot' to 'OpenClaw' in lore (openclaw#9119) * fix(memory): add input_type to Voyage AI embeddings for improved retrieval (openclaw#10818) * fix(memory): add input_type to Voyage AI embeddings for improved retrieval Voyage AI recommends passing input_type='document' when indexing and input_type='query' when searching. This improves retrieval quality by optimising the embedding space for each direction. Changes: - embedQuery now passes input_type: 'query' - embedBatch now passes input_type: 'document' - Batch API request_params includes input_type: 'document' - Tests updated to verify input_type is passed correctly * Changelog: note Voyage embeddings input_type fix (openclaw#10818) (thanks @mcinteerj) --------- Co-authored-by: Tak Hoffman <[email protected]> * fix(dashboard): restore tokenized control ui links * chore(skills): remove bird skill * chore(onboard): move xAI up in auth list * chore(release): 2026.2.6-1 * chore(onboard): move xAI below Google * ci: add concurrency controls, consolidate macOS jobs, optimize Windows CI * ci: re-enable parallel vitest on Windows CI * docs(changelog): note CI pipeline optimization (openclaw#10784) (thanks @mcaxtr) * fix(build): support daemon-cli .mjs bundles in compat shim * fix(docker): support .mjs entrypoints in images and e2e * test(hooks): stabilize session-memory hook tests * chore(release): 2026.2.6-2 * chore(onboard): reorder xAI + Qianfan providers * chore(release): 2026.2.6-3 * fix: comprehensive BlueBubbles and channel cleanup (openclaw#11093) * feat(bluebubbles): auto-strip markdown from outbound messages (openclaw#7402) * fix(security): add timeout to webhook body reading (openclaw#6762) Adds 30-second timeout to readBody() in voice-call, bluebubbles, and nostr webhook handlers. Prevents Slow-Loris DoS (CWE-400, CVSS 7.5). Merged with existing maxBytes protection in voice-call. * fix(security): unify Error objects and lint fixes in webhook timeouts (openclaw#6762) * fix: prevent plugins from auto-enabling without user consent (openclaw#3961) Changes default plugin enabled state from true to false in enablePluginEntry(). Preserves existing enabled:true values. Fixes openclaw#3932. * fix: apply hierarchical mediaMaxMb config to all channels (openclaw#8749) Generalizes resolveAttachmentMaxBytes() to use account → channel → global config resolution for all channels, not just BlueBubbles. Fixes openclaw#7847. * fix(bluebubbles): sanitize attachment filenames against header injection (openclaw#10333) Strip ", \r, \n, and \\ from filenames after path.basename() to prevent multipart Content-Disposition header injection (CWE-93, CVSS 5.4). Also adds sanitization to setGroupIconBlueBubbles which had zero filename sanitization. * fix(lint): exclude extensions/ from Oxlint preflight check (openclaw#9313) Extensions use PluginRuntime|null patterns that trigger no-redundant-type-constituents because PluginRuntime resolves to any. Excluding extensions/ from Oxlint unblocks user upgrades. Re-applies the approach from closed PR openclaw#10087. * fix(bluebubbles): add tempGuid to createNewChatWithMessage payload (openclaw#7745) Non-Private-API mode (AppleScript) requires tempGuid in send payloads. The main sendMessageBlueBubbles already had it, but createNewChatWithMessage was missing it, causing 400 errors for new chat creation without Private API. * fix: send stop-typing signal when run ends with NO_REPLY (openclaw#8785) Adds onCleanup callback to the typing controller that fires when the controller is cleaned up while typing was active (e.g., after NO_REPLY). Channels using createTypingCallbacks automatically get stop-typing on cleanup. This prevents the typing indicator from lingering in group chats when the agent decides not to reply. * fix(telegram): deduplicate skill commands in multi-agent setup (openclaw#5717) Two fixes: 1. Skip duplicate workspace dirs when listing skill commands across agents. Multiple agents sharing the same workspace would produce duplicate commands with _2, _3 suffixes. 2. Clear stale commands via deleteMyCommands before registering new ones. Commands from deleted skills now get cleaned up on restart. * fix: add size limits to unbounded in-memory caches (openclaw#4948) Adds max-size caps with oldest-entry eviction to prevent OOM in long-running deployments: - BlueBubbles serverInfoCache: 64 entries (already has TTL) - Google Chat authCache: 32 entries - Matrix directRoomCache: 1024 entries - Discord presenceCache: 5000 entries per account * fix: address review concerns (openclaw#11093) - Chain deleteMyCommands → setMyCommands to prevent race condition (openclaw#5717) - Rename enablePluginEntry to registerPluginEntry (now sets enabled: false) - Add Slow-Loris timeout test for readJsonBody (openclaw#6023) * docs: add symptom-first troubleshooting hub and deep runbooks (openclaw#11196) * docs(troubleshooting): add symptom-first troubleshooting runbooks * docs(troubleshooting): fix approvals command examples * docs(troubleshooting): wrap symptom cases in accordions * docs(automation): clarify userTimezone missing-key behavior * docs(troubleshooting): fix first-60-seconds ladder order * docs: add missing HEARTBEAT.md and MEMORY.md to bootstrap files list (openclaw#8105) * docs: add missing HEARTBEAT.md and MEMORY.md to bootstrap files list Fixes openclaw#7928 The documentation for skipBootstrap and workspace setup was missing HEARTBEAT.md and MEMORY.md from the bootstrap files list. Changes: - docs/gateway/configuration.md: Add HEARTBEAT.md and MEMORY.md - docs/zh-CN/gateway/configuration.md: Same for Chinese version - docs/start/openclaw.md: Add HEARTBEAT.md, clarify MEMORY.md is optional - docs/zh-CN/start/openclaw.md: Same for Chinese version * fix: reference PR number instead of issue in CHANGELOG * docs(workspace): align bootstrap file docs with runtime (openclaw#8105) --------- Co-authored-by: damaozi <[email protected]> Co-authored-by: Sebastian <[email protected]> * Agents: include runtime shell (openclaw#1835) * Agents: include runtime shell * Agents: fix compact runtime build * chore: fix CLAUDE.md formatting, security regex for secret --------- Co-authored-by: Tak hoffman <[email protected]> Co-authored-by: quotentiroler <[email protected]> * Web UI: show Compaction divider in chat history (openclaw#11341) * adding PR review workflow * added more explicit instructions * docs: canonicalize docs paths and align zh navigation (openclaw#11428) * docs(navigation): canonicalize paths and align zh nav * chore(docs): remove stray .DS_Store * docs(scripts): add non-mint docs link audit * docs(nav): fix zh source paths and preserve legacy redirects (openclaw#11428) (thanks @sebslight) * chore(docs): satisfy lint for docs link audit script (openclaw#11428) (thanks @sebslight) * chore: bump pi to 0.52.8 * Fix typo in FAQ regarding model configuration command (openclaw#6048) * CI: skip heavy jobs on docs-only changes (openclaw#11328) * fix: add .caf to AUDIO_FILE_EXTENSIONS (openclaw#10982) * fix: add .caf to AUDIO_FILE_EXTENSIONS for iMessage voice messages * fix: add caf audio extension regression coverage (openclaw#10982) (thanks @succ985) --------- Co-authored-by: succ985 <[email protected]> Co-authored-by: Gustavo Madeira Santana <[email protected]> * Gateway: fix multi-agent sessions.usage discovery (openclaw#11523) * Gateway: fix multi-agent sessions.usage discovery * Gateway: resolve sessions.usage keys via sessionId * feat(gateway): add agents.create/update/delete methods (openclaw#11045) * feat(gateway): add agents.create/update/delete methods * fix(lint): preserve memory-lancedb load error cause * feat(gateway): trash agent files on agents.delete * chore(protocol): regenerate Swift gateway models * fix(gateway): stabilize agents.create dirs and agentDir * feat(gateway): support avatar in agents.create * fix: prep agents.create/update/delete handlers (openclaw#11045) (thanks @advaitpaliwal) - Reuse movePathToTrash from browser/trash.ts (has ~/.Trash fallback on non-macOS) - Fix partial-failure: workspace setup now runs before config write - Always write Name to IDENTITY.md regardless of emoji/avatar - Add unit tests for agents.create, agents.update, agents.delete - Add CHANGELOG entry --------- Co-authored-by: Tyler Yust <[email protected]> * feat(sanitize): enhance context overflow error handling in user-facing text - Added tests to ensure proper sanitization of context overflow errors. - Introduced a new function to determine when to rewrite context overflow messages. - Updated the sanitization logic to improve user experience by providing clearer error messages while preserving conversational context. * fix(gateway): use LAN IP for WebSocket/probe URLs when bind=lan (openclaw#11448) * fix(gateway): use LAN IP for WebSocket/probe URLs when bind=lan (openclaw#11329) When gateway.bind=lan, the HTTP server correctly binds to 0.0.0.0 (all interfaces), but WebSocket connection URLs, probe targets, and Control UI links were hardcoded to 127.0.0.1. This caused CLI commands and status probes to show localhost-only URLs even in LAN mode, and made onboarding display misleading connection info. - Add pickPrimaryLanIPv4() to gateway/net.ts to detect the machine's primary LAN IPv4 address (prefers en0/eth0, falls back to any external interface) - Update pickProbeHostForBind() to use LAN IP when bind=lan - Update buildGatewayConnectionDetails() to use LAN IP and report "local lan <ip>" as the URL source - Update resolveControlUiLinks() to return LAN-accessible URLs - Update probe note in status.gather.ts to reflect new behavior - Add tests for pickPrimaryLanIPv4 and bind=lan URL resolution Closes openclaw#11329 Co-authored-by: Cursor <[email protected]> * test: move vi.restoreAllMocks to afterEach in pickPrimaryLanIPv4 Per review feedback: avoid calling vi.restoreAllMocks() inside individual tests as it restores all spies globally and can cause ordering issues. Use afterEach in the describe block instead. Co-authored-by: Cursor <[email protected]> * Changelog: note LAN bind URLs fix (openclaw#11448) (thanks @AnonO6) --------- Co-authored-by: Cursor <[email protected]> Co-authored-by: Tak Hoffman <[email protected]> * fix: recover from context overflow caused by oversized tool results (openclaw#11579) * fix: gracefully handle oversized tool results causing context overflow When a subagent reads a very large file or gets a huge tool result (e.g., gh pr diff on a massive PR), it can exceed the model's context window in a single prompt. Auto-compaction can't help because there's no older history to compact — just one giant tool result. This adds two layers of defense: 1. Pre-emptive: Hard cap on tool result size (400K chars ≈ 100K tokens) applied in the session tool result guard before persistence. This prevents extremely large tool results from being stored in full, regardless of model context window size. 2. Recovery: When context overflow is detected and compaction fails, scan session messages for oversized tool results relative to the model's actual context window (30% max share). If found, truncate them in the session via branching (creating a new branch with truncated content) and retry the prompt. The truncation preserves the beginning of the content (most useful for understanding what was read) and appends a notice explaining the truncation and suggesting offset/limit parameters for targeted reads. Includes comprehensive tests for: - Text truncation with newline-boundary awareness - Context-window-proportional size calculation - In-memory message truncation - Oversized detection heuristics - Guard-level size capping during persistence * fix: prep fixes for tool result truncation PR (openclaw#11579) (thanks @tyler6204) * Memory: harden QMD startup, timeouts, and fallback recovery * Memory: queue forced QMD sync and handle sqlite busy reads * Memory: chain forced QMD queue and fail over on busy index * Memory: make QMD cache eviction callback idempotent * Memory: add SQLITE_BUSY fallback regression test * Update CHANGELOG.md for version 2026.2.6-4: Added RPC methods for agent management, fixed context overflow recovery, improved LAN IP handling, enhanced memory retrieval, and updated media understanding for audio transcription. * Tests: harden flake hotspots and consolidate provider-auth suites (openclaw#11598) * Tests: harden flake hotspots and consolidate provider-auth suites * Tests: restore env vars by deleting missing snapshot values * Tests: use real newline in memory summary filter case * Tests(memory): use fake timers for qmd timeout coverage * Changelog: add tests hardening entry for openclaw#11598 * docs: clarify onboarding instructions for beginners (openclaw#10956) * chore: updated PR review skills and workflow info on tests + fake timers * Fix Nix repository link in README (openclaw#7910) Updated Nix repository link in README. Co-authored-by: Josh <[email protected]> Co-authored-by: Seb Slight <[email protected]> * Docs: fix cron.update param name id → jobId (openclaw#11365) (openclaw#11467) * Docs: fix cron.update param name id → jobId (openclaw#11365) * Docs: sync zh-CN cron.update param name id → jobId * docs: revert manual zh-CN generated docs edit (openclaw#11467) (thanks @lailoo) --------- Co-authored-by: damaozi <[email protected]> Co-authored-by: Sebastian <[email protected]> * fix: use STATE_DIR instead of hardcoded ~/.openclaw for identity and canvas (openclaw#4824) * fix: use STATE_DIR instead of hardcoded ~/.openclaw for identity and canvas device-identity.ts and canvas-host/server.ts used hardcoded path.join(os.homedir(), '.openclaw', ...) ignoring OPENCLAW_STATE_DIR env var and the resolveStateDir() logic from config/paths.ts. This caused ~/.openclaw/identity and ~/.openclaw/canvas directories to be created even when state dir was overridden or resided elsewhere. * fix: format and remove duplicate imports * fix: scope state-dir patch + add regression tests (openclaw#4824) (thanks @kossoy) * fix: align state-dir fallbacks in hooks and agent paths (openclaw#4824) (thanks @kossoy) --------- Co-authored-by: Gustavo Madeira Santana <[email protected]> * fix(cron): share isolated announce flow + harden cron scheduling/delivery (openclaw#11641) * fix(cron): comprehensive cron scheduling and delivery fixes - Fix delivery target resolution for isolated agent cron jobs - Improve schedule parsing and validation - Add job retry logic and error handling - Enhance cron ops with better state management - Add timer improvements for more reliable cron execution - Add cron event type to protocol schema - Support cron events in heartbeat runner (skip empty-heartbeat check, use dedicated CRON_EVENT_PROMPT for relay) * fix: remove cron debug test and add changelog/docs notes (openclaw#11641) (thanks @tyler6204) * fix: context overflow compaction and subagent announce improvements (openclaw#11664) (thanks @tyler6204) * initial commit * feat: implement deriveSessionTotalTokens function and update usage tests * Added deriveSessionTotalTokens function to calculate total tokens based on usage and context tokens. * Updated usage tests to include cases for derived session total tokens. * Refactored session usage calculations in multiple files to utilize the new function for improved accuracy. * fix: restore overflow truncation fallback + changelog/test hardening (openclaw#11551) (thanks @tyler6204) * fix(ui): smooth chat refresh scroll and suppress new-messages badge flash * fix(discord): support forum channel thread-create (openclaw#10062) * fix(discord): support forum channel thread-create * fix: harden discord forum thread-create (openclaw#10062) (thanks @jarvis89757) --------- Co-authored-by: Shakker <[email protected]> * feat(telegram): add spoiler tag support (openclaw#11543) * feat(telegram): add spoiler tag support Render markdown ||spoiler|| syntax as <tg-spoiler> tags in Telegram HTML output. The markdown IR already parses spoiler syntax, but the Telegram renderer was missing the style marker. This adds the spoiler marker to renderTelegramHtml(). Fixes spoiler text appearing as raw ||text|| instead of hidden text. * fix: enable Telegram spoiler rendering (openclaw#11543) (thanks @ezhikkk) --------- Co-authored-by: Параша <[email protected]> Co-authored-by: Muhammed Mukhthar CM <[email protected]> * fix(doctor): suppress repeated legacy state migration warnings (openclaw#11709) * fix(doctor): suppress repeated state migration warning * fix: harden state-dir mirror detection + warnings (openclaw#11709) (thanks @gumadeiras) * test: cover mirror hardening edge cases (openclaw#11709) (thanks @gumadeiras) * CI: scope heavy jobs, build once, and remove duplicate validation work (openclaw#11570) * CI: scope jobs and reuse build artifacts * CI: fix scope fallback and remove unused artifact job * CI: remove setup-node pnpm cache inputs * CI: add pnpm store cache and dist artifact smoke * CI: extract pnpm cache action and consume dist artifact * chore: centralizing warning filters * chore: suppress warnings for node default output path * chore: project hygiene — fix workspace:*, sandbox USER, dead config (openclaw#11289) * chore: project hygiene fixes (workspace:*, sandbox USER, dead config) * chore: also fix workspace:* in zalouser dependencies * docs: add security & trust documentation Add threat model (MITRE ATLAS), contribution guide, and security directory README. Update SECURITY.md with trust page reporting instructions and Jamieson O'Reilly as Security & Trust. Co-Authored-By: theonejvo <[email protected]> * Centralize date/time formatting utilities (openclaw#11831) * chore: fix vitest standalone configs and update package description (openclaw#11865) * chore: fix vitest standalone configs and update package description - vitest.live.config.ts and vitest.e2e.config.ts now extend root config - Inherits testTimeout (120s), resolve.alias, pool, setupFiles, excludes - ui/vitest.node.config.ts gets explicit 120s timeout - package.json description updated for multi-channel AI gateway - Removed unused src/utils/time-format.ts * chore: filter inherited excludes in live/e2e vitest configs * refactor: dedupe GroupPolicy/DmPolicy in extensions Import from openclaw/plugin-sdk instead of re-declaring identical types. * Add GitHub Copilot models to xhigh list (openclaw#11646) * Add GitHub Copilot models to xhigh list * fix(thinking): add xhigh copilot tests and changelog (openclaw#11646) (thanks @seans-openclawbot) --------- Co-authored-by: Sean Dai <[email protected]> Co-authored-by: Sebastian <[email protected]> * Exec approvals: render forwarded commands in monospace (openclaw#11937) * fix(exec-approvals): format forwarded commands as code * fix(exec-approvals): place fenced command blocks on new line (openclaw#11937) (thanks @sebslight) * docs: fix changelog PR reference Fix Exec approvals command text formatting issue for safer approval scanning. * Gateway/Plugins: device pairing + phone control plugins (openclaw#11755) * iOS: alpha node app + setup-code onboarding (openclaw#11756) * Memory/QMD: warn when scope denies search * Docs i18n: make translation prompt language-pluggable * Docs: seed ja-JP translations * Docs: use ja-jp Mintlify language code * Docs: note ja-JP docs POC in changelog (openclaw#11988) (thanks @joshp123) * Docs: fix language switcher order + Japanese locale * Docs: note language switcher ordering + JP flag fix (openclaw#12023) (thanks @joshp123) * fix(paths): respect OPENCLAW_HOME for all internal path resolution (openclaw#12091) * fix(paths): respect OPENCLAW_HOME for all internal path resolution (openclaw#11995) Add home-dir module (src/infra/home-dir.ts) that centralizes home directory resolution with precedence: OPENCLAW_HOME > HOME > USERPROFILE > os.homedir(). Migrate all path-sensitive callsites: config IO, agent dirs, session transcripts, pairing store, cron store, doctor, CLI profiles. Add envHomedir() helper in config/paths.ts to reduce lambda noise. Document OPENCLAW_HOME in docs/help/environment.md. * fix(paths): handle OPENCLAW_HOME '~' fallback (openclaw#12091) (thanks @sebslight) * docs: mention OPENCLAW_HOME in install and getting started (openclaw#12091) (thanks @sebslight) * fix(status): show OPENCLAW_HOME in shortened paths (openclaw#12091) (thanks @sebslight) * docs(changelog): clarify OPENCLAW_HOME and HOME precedence (openclaw#12091) (thanks @sebslight) * changelog: split openclaw#12091 entry into Added + Fixes * fix(config): clamp maxTokens to contextWindow to prevent invalid configurations Closes openclaw#5308 When users configure maxTokens larger than contextWindow (e.g., maxTokens: 40960 with contextWindow: 32768), the model may fail silently. This fix clamps maxTokens to be at most contextWindow, preventing such invalid configurations. * test(config): cover maxTokens clamping * chore(changelog): note maxTokens clamp (openclaw#5516) (thanks @lailoo) (openclaw#12139) * fix: more merge fixes * fix: fix gauranteed rejection when declaredCommands undefined * fix: resolve build errors and eslint warnings - Add missing parseDatedFilename function to memory/internal.ts - Remove reference to undefined thinkingWarning variable - Fix node.invoke guard to maintain backward compatibility - Rename unused runtimeConfig variable to _runtimeConfig Co-Authored-By: Claude Sonnet 4.5 <[email protected]> --------- Co-authored-by: ideoutrea <[email protected]> Co-authored-by: ide-rea <[email protected]> Co-authored-by: Tak Hoffman <[email protected]> Co-authored-by: Yida-Dev <[email protected]> Co-authored-by: Yida-Dev <[email protected]> Co-authored-by: Claude Opus 4.6 <[email protected]> Co-authored-by: Gustavo Madeira Santana <[email protected]> Co-authored-by: Jake <[email protected]> Co-authored-by: calvin-hpnet <[email protected]> Co-authored-by: Shadril Hassan Shifat <[email protected]> Co-authored-by: Peter Steinberger <[email protected]> Co-authored-by: gitpds <[email protected]> Co-authored-by: Seb Slight <[email protected]> Co-authored-by: Raymond Berger <[email protected]> Co-authored-by: Tyler Yust <[email protected]> Co-authored-by: DEOKLYONG MOON <[email protected]> Co-authored-by: Val Alexander <[email protected]> Co-authored-by: Markus Buhatem Koch <[email protected]> Co-authored-by: Marcus Castro <[email protected]> Co-authored-by: 大猫子 <[email protected]> Co-authored-by: damaozi <[email protected]> Co-authored-by: Tak hoffman <[email protected]> Co-authored-by: quotentiroler <[email protected]> Co-authored-by: Abdullah <[email protected]> Co-authored-by: max <[email protected]> Co-authored-by: succ985 <[email protected]> Co-authored-by: succ985 <[email protected]> Co-authored-by: Advait Paliwal <[email protected]> Co-authored-by: Tyler Yust <[email protected]> Co-authored-by: Aviral <[email protected]> Co-authored-by: Cursor <[email protected]> Co-authored-by: Vignesh Natarajan <[email protected]> Co-authored-by: Gustavo Madeira Santana <[email protected]> Co-authored-by: Rohan Patil <[email protected]> Co-authored-by: danielcadenhead <[email protected]> Co-authored-by: Josh <[email protected]> Co-authored-by: Oleg Kossoy <[email protected]> Co-authored-by: jarvis89757 <[email protected]> Co-authored-by: Shakker <[email protected]> Co-authored-by: ezhikkk <[email protected]> Co-authored-by: Параша <[email protected]> Co-authored-by: Muhammed Mukhthar CM <[email protected]> Co-authored-by: theonejvo <[email protected]> Co-authored-by: seans-openclawbot <[email protected]> Co-authored-by: Sean Dai <[email protected]> Co-authored-by: Mariano Belinky <[email protected]> Co-authored-by: Josh Palmer <[email protected]> Co-authored-by: George Pickett <[email protected]>
…law#11709) * fix(doctor): suppress repeated state migration warning * fix: harden state-dir mirror detection + warnings (openclaw#11709) (thanks @gumadeiras) * test: cover mirror hardening edge cases (openclaw#11709) (thanks @gumadeiras)
* Add baidu qianfan model provider * Add baidu qianfan model provider * Fix format * Optimize doc * optimize doc * Fix import error * Add auth choice * Optimize format * Optimize doc * Fix key resolve * Optimize import * Support ERNIE-5.0-Thinking-Preview * Resolve conflicts * Fix conflicts * Docs: add PR sign-off template (openclaw#10561) * fix: guard resolveUserPath against undefined input (openclaw#10176) * fix: guard resolveUserPath against undefined input When subagent spawner omits workspaceDir, resolveUserPath receives undefined and crashes on .trim(). Add a falsy guard that falls back to process.cwd(), matching the behavior callers already expect. Closes openclaw#10089 Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: harden runner workspace fallback (openclaw#10176) (thanks @Yida-Dev) * fix: harden workspace fallback scoping (openclaw#10176) (thanks @Yida-Dev) * refactor: centralize workspace fallback classification and redaction (openclaw#10176) (thanks @Yida-Dev) * test: remove explicit any from utils mock (openclaw#10176) (thanks @Yida-Dev) * security: reject malformed agent session keys for workspace resolution (openclaw#10176) (thanks @Yida-Dev) --------- Co-authored-by: Yida-Dev <[email protected]> Co-authored-by: Claude Opus 4.6 <[email protected]> Co-authored-by: Gustavo Madeira Santana <[email protected]> * Docs: revise PR and issue submission guides (openclaw#10617) * Docs: revise PR submission guide * Docs: revise issue submission guide * feat(memory): native Voyage AI support (openclaw#7078) * feat(memory): add native Voyage AI embedding support with batching Cherry-picked from PR openclaw#2519, resolved conflict in memory-search.ts (hasRemote -> hasRemoteConfig rename + added voyage provider) * fix(memory): optimize voyage batch memory usage with streaming and deduplicate code Cherry-picked from PR openclaw#2519. Fixed lint error: changed this.runWithConcurrency to use imported runWithConcurrency function after extraction to internal.ts * feat(memory): document Voyage embeddings + VOYAGE_API_KEY (openclaw#7078) (thanks @mcinteerj) (openclaw#10699) * feat(antigravity): update default model to Claude Opus 4.6 (openclaw#10720) * feat(antigravity): update default model to Claude Opus 4.6 Claude Opus 4.5 has been replaced by Claude Opus 4.6 on the Antigravity (Google Cloud Code Assist) platform. - Update DEFAULT_MODEL in google-antigravity-auth extension - Update testing docs to reference the new model * fix: update remaining antigravity opus 4.5 refs in zh-CN docs and tests Address review comments from Greptile: - Update zh-CN/testing.md antigravity model references - Update pi-tools-agent-config.test.ts model IDs * Antigravity: default OAuth model to Opus 4.6 (openclaw#10720) (thanks @calvin-hpnet) --------- Co-authored-by: Tak Hoffman <[email protected]> * fix(hooks): replace debug console.log with proper subsystem logging in session-memory (openclaw#10730) * fix: replace debug console.log with proper subsystem logging in session-memory * fix(hooks): normalize session-memory subsystem logging --------- Co-authored-by: Tak Hoffman <[email protected]> * docs(changelog): prepare 2026.2.6 * docs(changelog): include merged PRs since v2026.2.3 * chore(release): bump version to 2026.2.6 * fix(telegram): cast fetch for grammY ApiClientOptions * docs: fix markdownlint fragments + headings * docs(changelog): refresh 2026.2.6 since v2026.2.3 * docs(imessage): add macOS TCC troubleshooting * docs(imessage): improve macOS TCC troubleshooting guidance (openclaw#10781) * chore(deps): update deps * fix(agents): add Opus 4.6 forward-compat fallback * chore(deps): bump carbon beta * docs(changelog): curate 2026.2.6 * docs(changelog): highlight Opus 4.6 + Codex 5.3 first * Fix QMD CLI installation link in memory.md (openclaw#8647) Correct the installation link for the QMD CLI in the documentation. * chore(lockfile): fix pnpm-lock * fix: cron scheduler reliability, store hardening, and UX improvements (openclaw#10776) * refactor: update cron job wake mode and run mode handling - Changed default wake mode from 'next-heartbeat' to 'now' in CronJobEditor and related CLI commands. - Updated cron-tool tests to reflect changes in run mode, introducing 'due' and 'force' options. - Enhanced cron-tool logic to handle new run modes and ensure compatibility with existing job structures. - Added new tests for delivery plan consistency and job execution behavior under various conditions. - Improved normalization functions to handle wake mode and session target casing. This refactor aims to streamline cron job configurations and enhance the overall user experience with clearer defaults and improved functionality. * test: enhance cron job functionality and UI - Added tests to ensure the isolated agent correctly announces the final payload text when delivering messages via Telegram. - Implemented a new function to pick the last deliverable payload from a list of delivery payloads. - Enhanced the cron service to maintain legacy "every" jobs while minute cron jobs recompute schedules. - Updated the cron store migration tests to verify the addition of anchorMs to legacy every schedules. - Improved the UI for displaying cron job details, including job state and delivery information, with new styles and layout adjustments. These changes aim to improve the reliability and user experience of the cron job system. * test: enhance sessions thinking level handling - Added tests to verify that the correct thinking levels are applied during session spawning. - Updated the sessions-spawn-tool to include a new parameter for overriding thinking levels. - Enhanced the UI to support additional thinking levels, including "xhigh" and "full", and improved the handling of current options in dropdowns. These changes aim to improve the flexibility and accuracy of thinking level configurations in session management. * feat: enhance session management and cron job functionality - Introduced passthrough arguments in the test-parallel script to allow for flexible command-line options. - Updated session handling to hide cron run alias session keys from the sessions list, improving clarity. - Enhanced the cron service to accurately record job start times and durations, ensuring better tracking of job execution. - Added tests to verify the correct behavior of the cron service under various conditions, including zero-delay timers. These changes aim to improve the usability and reliability of session and cron job management. * feat: implement job running state checks in cron service - Added functionality to prevent manual job runs if a job is already in progress, enhancing job management. - Updated the `isJobDue` function to include checks for running jobs, ensuring accurate scheduling. - Enhanced the `run` function to return a specific reason when a job is already running. - Introduced a new test case to verify the behavior of forced manual runs during active job execution. These changes aim to improve the reliability and clarity of cron job execution and management. * feat: add session ID and key to CronRunLogEntry model - Introduced `sessionid` and `sessionkey` properties to the `CronRunLogEntry` struct for enhanced tracking of session-related information. - Updated the initializer and Codable conformance to accommodate the new properties, ensuring proper serialization and deserialization. These changes aim to improve the granularity of logging and session management within the cron job system. * fix: improve session display name resolution - Updated the `resolveSessionDisplayName` function to ensure that both label and displayName are trimmed and default to an empty string if not present. - Enhanced the logic to prevent returning the key if it matches the label or displayName, improving clarity in session naming. These changes aim to enhance the accuracy and usability of session display names in the UI. * perf: skip cron store persist when idle timer tick produces no changes recomputeNextRuns now returns a boolean indicating whether any job state was mutated. The idle path in onTimer only persists when the return value is true, eliminating unnecessary file writes every 60s for far-future or idle schedules. * fix: prep for merge - explicit delivery mode migration, docs + changelog (openclaw#10776) (thanks @tyler6204) * Docs: fix broken /plugins links (openclaw#9308) * Docs: fix broken /plugins links to /plugin The documentation linked to /plugins which doesn't exist. The correct path is /plugin (singular) which contains the plugins overview documentation. Co-Authored-By: Claude Opus 4.5 <[email protected]> * docs: drop manual zh-CN doc edits from plugins link fix --------- Co-authored-by: Claude Opus 4.5 <[email protected]> Co-authored-by: Sebastian <[email protected]> * fix(build): unblock pnpm build dts * Fix repository links in formal-verification.md (openclaw#10200) Updated repository links for formal verification models. * Revert previous change from 'Clawdbot' to 'OpenClaw' in lore (openclaw#9119) * fix(memory): add input_type to Voyage AI embeddings for improved retrieval (openclaw#10818) * fix(memory): add input_type to Voyage AI embeddings for improved retrieval Voyage AI recommends passing input_type='document' when indexing and input_type='query' when searching. This improves retrieval quality by optimising the embedding space for each direction. Changes: - embedQuery now passes input_type: 'query' - embedBatch now passes input_type: 'document' - Batch API request_params includes input_type: 'document' - Tests updated to verify input_type is passed correctly * Changelog: note Voyage embeddings input_type fix (openclaw#10818) (thanks @mcinteerj) --------- Co-authored-by: Tak Hoffman <[email protected]> * fix(dashboard): restore tokenized control ui links * chore(skills): remove bird skill * chore(onboard): move xAI up in auth list * chore(release): 2026.2.6-1 * chore(onboard): move xAI below Google * ci: add concurrency controls, consolidate macOS jobs, optimize Windows CI * ci: re-enable parallel vitest on Windows CI * docs(changelog): note CI pipeline optimization (openclaw#10784) (thanks @mcaxtr) * fix(build): support daemon-cli .mjs bundles in compat shim * fix(docker): support .mjs entrypoints in images and e2e * test(hooks): stabilize session-memory hook tests * chore(release): 2026.2.6-2 * chore(onboard): reorder xAI + Qianfan providers * chore(release): 2026.2.6-3 * fix: comprehensive BlueBubbles and channel cleanup (openclaw#11093) * feat(bluebubbles): auto-strip markdown from outbound messages (openclaw#7402) * fix(security): add timeout to webhook body reading (openclaw#6762) Adds 30-second timeout to readBody() in voice-call, bluebubbles, and nostr webhook handlers. Prevents Slow-Loris DoS (CWE-400, CVSS 7.5). Merged with existing maxBytes protection in voice-call. * fix(security): unify Error objects and lint fixes in webhook timeouts (openclaw#6762) * fix: prevent plugins from auto-enabling without user consent (openclaw#3961) Changes default plugin enabled state from true to false in enablePluginEntry(). Preserves existing enabled:true values. Fixes openclaw#3932. * fix: apply hierarchical mediaMaxMb config to all channels (openclaw#8749) Generalizes resolveAttachmentMaxBytes() to use account → channel → global config resolution for all channels, not just BlueBubbles. Fixes openclaw#7847. * fix(bluebubbles): sanitize attachment filenames against header injection (openclaw#10333) Strip ", \r, \n, and \\ from filenames after path.basename() to prevent multipart Content-Disposition header injection (CWE-93, CVSS 5.4). Also adds sanitization to setGroupIconBlueBubbles which had zero filename sanitization. * fix(lint): exclude extensions/ from Oxlint preflight check (openclaw#9313) Extensions use PluginRuntime|null patterns that trigger no-redundant-type-constituents because PluginRuntime resolves to any. Excluding extensions/ from Oxlint unblocks user upgrades. Re-applies the approach from closed PR openclaw#10087. * fix(bluebubbles): add tempGuid to createNewChatWithMessage payload (openclaw#7745) Non-Private-API mode (AppleScript) requires tempGuid in send payloads. The main sendMessageBlueBubbles already had it, but createNewChatWithMessage was missing it, causing 400 errors for new chat creation without Private API. * fix: send stop-typing signal when run ends with NO_REPLY (openclaw#8785) Adds onCleanup callback to the typing controller that fires when the controller is cleaned up while typing was active (e.g., after NO_REPLY). Channels using createTypingCallbacks automatically get stop-typing on cleanup. This prevents the typing indicator from lingering in group chats when the agent decides not to reply. * fix(telegram): deduplicate skill commands in multi-agent setup (openclaw#5717) Two fixes: 1. Skip duplicate workspace dirs when listing skill commands across agents. Multiple agents sharing the same workspace would produce duplicate commands with _2, _3 suffixes. 2. Clear stale commands via deleteMyCommands before registering new ones. Commands from deleted skills now get cleaned up on restart. * fix: add size limits to unbounded in-memory caches (openclaw#4948) Adds max-size caps with oldest-entry eviction to prevent OOM in long-running deployments: - BlueBubbles serverInfoCache: 64 entries (already has TTL) - Google Chat authCache: 32 entries - Matrix directRoomCache: 1024 entries - Discord presenceCache: 5000 entries per account * fix: address review concerns (openclaw#11093) - Chain deleteMyCommands → setMyCommands to prevent race condition (openclaw#5717) - Rename enablePluginEntry to registerPluginEntry (now sets enabled: false) - Add Slow-Loris timeout test for readJsonBody (openclaw#6023) * docs: add symptom-first troubleshooting hub and deep runbooks (openclaw#11196) * docs(troubleshooting): add symptom-first troubleshooting runbooks * docs(troubleshooting): fix approvals command examples * docs(troubleshooting): wrap symptom cases in accordions * docs(automation): clarify userTimezone missing-key behavior * docs(troubleshooting): fix first-60-seconds ladder order * docs: add missing HEARTBEAT.md and MEMORY.md to bootstrap files list (openclaw#8105) * docs: add missing HEARTBEAT.md and MEMORY.md to bootstrap files list Fixes openclaw#7928 The documentation for skipBootstrap and workspace setup was missing HEARTBEAT.md and MEMORY.md from the bootstrap files list. Changes: - docs/gateway/configuration.md: Add HEARTBEAT.md and MEMORY.md - docs/zh-CN/gateway/configuration.md: Same for Chinese version - docs/start/openclaw.md: Add HEARTBEAT.md, clarify MEMORY.md is optional - docs/zh-CN/start/openclaw.md: Same for Chinese version * fix: reference PR number instead of issue in CHANGELOG * docs(workspace): align bootstrap file docs with runtime (openclaw#8105) --------- Co-authored-by: damaozi <[email protected]> Co-authored-by: Sebastian <[email protected]> * Agents: include runtime shell (openclaw#1835) * Agents: include runtime shell * Agents: fix compact runtime build * chore: fix CLAUDE.md formatting, security regex for secret --------- Co-authored-by: Tak hoffman <[email protected]> Co-authored-by: quotentiroler <[email protected]> * Web UI: show Compaction divider in chat history (openclaw#11341) * adding PR review workflow * added more explicit instructions * docs: canonicalize docs paths and align zh navigation (openclaw#11428) * docs(navigation): canonicalize paths and align zh nav * chore(docs): remove stray .DS_Store * docs(scripts): add non-mint docs link audit * docs(nav): fix zh source paths and preserve legacy redirects (openclaw#11428) (thanks @sebslight) * chore(docs): satisfy lint for docs link audit script (openclaw#11428) (thanks @sebslight) * chore: bump pi to 0.52.8 * Fix typo in FAQ regarding model configuration command (openclaw#6048) * CI: skip heavy jobs on docs-only changes (openclaw#11328) * fix: add .caf to AUDIO_FILE_EXTENSIONS (openclaw#10982) * fix: add .caf to AUDIO_FILE_EXTENSIONS for iMessage voice messages * fix: add caf audio extension regression coverage (openclaw#10982) (thanks @succ985) --------- Co-authored-by: succ985 <[email protected]> Co-authored-by: Gustavo Madeira Santana <[email protected]> * Gateway: fix multi-agent sessions.usage discovery (openclaw#11523) * Gateway: fix multi-agent sessions.usage discovery * Gateway: resolve sessions.usage keys via sessionId * feat(gateway): add agents.create/update/delete methods (openclaw#11045) * feat(gateway): add agents.create/update/delete methods * fix(lint): preserve memory-lancedb load error cause * feat(gateway): trash agent files on agents.delete * chore(protocol): regenerate Swift gateway models * fix(gateway): stabilize agents.create dirs and agentDir * feat(gateway): support avatar in agents.create * fix: prep agents.create/update/delete handlers (openclaw#11045) (thanks @advaitpaliwal) - Reuse movePathToTrash from browser/trash.ts (has ~/.Trash fallback on non-macOS) - Fix partial-failure: workspace setup now runs before config write - Always write Name to IDENTITY.md regardless of emoji/avatar - Add unit tests for agents.create, agents.update, agents.delete - Add CHANGELOG entry --------- Co-authored-by: Tyler Yust <[email protected]> * feat(sanitize): enhance context overflow error handling in user-facing text - Added tests to ensure proper sanitization of context overflow errors. - Introduced a new function to determine when to rewrite context overflow messages. - Updated the sanitization logic to improve user experience by providing clearer error messages while preserving conversational context. * fix(gateway): use LAN IP for WebSocket/probe URLs when bind=lan (openclaw#11448) * fix(gateway): use LAN IP for WebSocket/probe URLs when bind=lan (openclaw#11329) When gateway.bind=lan, the HTTP server correctly binds to 0.0.0.0 (all interfaces), but WebSocket connection URLs, probe targets, and Control UI links were hardcoded to 127.0.0.1. This caused CLI commands and status probes to show localhost-only URLs even in LAN mode, and made onboarding display misleading connection info. - Add pickPrimaryLanIPv4() to gateway/net.ts to detect the machine's primary LAN IPv4 address (prefers en0/eth0, falls back to any external interface) - Update pickProbeHostForBind() to use LAN IP when bind=lan - Update buildGatewayConnectionDetails() to use LAN IP and report "local lan <ip>" as the URL source - Update resolveControlUiLinks() to return LAN-accessible URLs - Update probe note in status.gather.ts to reflect new behavior - Add tests for pickPrimaryLanIPv4 and bind=lan URL resolution Closes openclaw#11329 Co-authored-by: Cursor <[email protected]> * test: move vi.restoreAllMocks to afterEach in pickPrimaryLanIPv4 Per review feedback: avoid calling vi.restoreAllMocks() inside individual tests as it restores all spies globally and can cause ordering issues. Use afterEach in the describe block instead. Co-authored-by: Cursor <[email protected]> * Changelog: note LAN bind URLs fix (openclaw#11448) (thanks @AnonO6) --------- Co-authored-by: Cursor <[email protected]> Co-authored-by: Tak Hoffman <[email protected]> * fix: recover from context overflow caused by oversized tool results (openclaw#11579) * fix: gracefully handle oversized tool results causing context overflow When a subagent reads a very large file or gets a huge tool result (e.g., gh pr diff on a massive PR), it can exceed the model's context window in a single prompt. Auto-compaction can't help because there's no older history to compact — just one giant tool result. This adds two layers of defense: 1. Pre-emptive: Hard cap on tool result size (400K chars ≈ 100K tokens) applied in the session tool result guard before persistence. This prevents extremely large tool results from being stored in full, regardless of model context window size. 2. Recovery: When context overflow is detected and compaction fails, scan session messages for oversized tool results relative to the model's actual context window (30% max share). If found, truncate them in the session via branching (creating a new branch with truncated content) and retry the prompt. The truncation preserves the beginning of the content (most useful for understanding what was read) and appends a notice explaining the truncation and suggesting offset/limit parameters for targeted reads. Includes comprehensive tests for: - Text truncation with newline-boundary awareness - Context-window-proportional size calculation - In-memory message truncation - Oversized detection heuristics - Guard-level size capping during persistence * fix: prep fixes for tool result truncation PR (openclaw#11579) (thanks @tyler6204) * Memory: harden QMD startup, timeouts, and fallback recovery * Memory: queue forced QMD sync and handle sqlite busy reads * Memory: chain forced QMD queue and fail over on busy index * Memory: make QMD cache eviction callback idempotent * Memory: add SQLITE_BUSY fallback regression test * Update CHANGELOG.md for version 2026.2.6-4: Added RPC methods for agent management, fixed context overflow recovery, improved LAN IP handling, enhanced memory retrieval, and updated media understanding for audio transcription. * Tests: harden flake hotspots and consolidate provider-auth suites (openclaw#11598) * Tests: harden flake hotspots and consolidate provider-auth suites * Tests: restore env vars by deleting missing snapshot values * Tests: use real newline in memory summary filter case * Tests(memory): use fake timers for qmd timeout coverage * Changelog: add tests hardening entry for openclaw#11598 * docs: clarify onboarding instructions for beginners (openclaw#10956) * chore: updated PR review skills and workflow info on tests + fake timers * Fix Nix repository link in README (openclaw#7910) Updated Nix repository link in README. Co-authored-by: Josh <[email protected]> Co-authored-by: Seb Slight <[email protected]> * Docs: fix cron.update param name id → jobId (openclaw#11365) (openclaw#11467) * Docs: fix cron.update param name id → jobId (openclaw#11365) * Docs: sync zh-CN cron.update param name id → jobId * docs: revert manual zh-CN generated docs edit (openclaw#11467) (thanks @lailoo) --------- Co-authored-by: damaozi <[email protected]> Co-authored-by: Sebastian <[email protected]> * fix: use STATE_DIR instead of hardcoded ~/.openclaw for identity and canvas (openclaw#4824) * fix: use STATE_DIR instead of hardcoded ~/.openclaw for identity and canvas device-identity.ts and canvas-host/server.ts used hardcoded path.join(os.homedir(), '.openclaw', ...) ignoring OPENCLAW_STATE_DIR env var and the resolveStateDir() logic from config/paths.ts. This caused ~/.openclaw/identity and ~/.openclaw/canvas directories to be created even when state dir was overridden or resided elsewhere. * fix: format and remove duplicate imports * fix: scope state-dir patch + add regression tests (openclaw#4824) (thanks @kossoy) * fix: align state-dir fallbacks in hooks and agent paths (openclaw#4824) (thanks @kossoy) --------- Co-authored-by: Gustavo Madeira Santana <[email protected]> * fix(cron): share isolated announce flow + harden cron scheduling/delivery (openclaw#11641) * fix(cron): comprehensive cron scheduling and delivery fixes - Fix delivery target resolution for isolated agent cron jobs - Improve schedule parsing and validation - Add job retry logic and error handling - Enhance cron ops with better state management - Add timer improvements for more reliable cron execution - Add cron event type to protocol schema - Support cron events in heartbeat runner (skip empty-heartbeat check, use dedicated CRON_EVENT_PROMPT for relay) * fix: remove cron debug test and add changelog/docs notes (openclaw#11641) (thanks @tyler6204) * fix: context overflow compaction and subagent announce improvements (openclaw#11664) (thanks @tyler6204) * initial commit * feat: implement deriveSessionTotalTokens function and update usage tests * Added deriveSessionTotalTokens function to calculate total tokens based on usage and context tokens. * Updated usage tests to include cases for derived session total tokens. * Refactored session usage calculations in multiple files to utilize the new function for improved accuracy. * fix: restore overflow truncation fallback + changelog/test hardening (openclaw#11551) (thanks @tyler6204) * fix(ui): smooth chat refresh scroll and suppress new-messages badge flash * fix(discord): support forum channel thread-create (openclaw#10062) * fix(discord): support forum channel thread-create * fix: harden discord forum thread-create (openclaw#10062) (thanks @jarvis89757) --------- Co-authored-by: Shakker <[email protected]> * feat(telegram): add spoiler tag support (openclaw#11543) * feat(telegram): add spoiler tag support Render markdown ||spoiler|| syntax as <tg-spoiler> tags in Telegram HTML output. The markdown IR already parses spoiler syntax, but the Telegram renderer was missing the style marker. This adds the spoiler marker to renderTelegramHtml(). Fixes spoiler text appearing as raw ||text|| instead of hidden text. * fix: enable Telegram spoiler rendering (openclaw#11543) (thanks @ezhikkk) --------- Co-authored-by: Параша <[email protected]> Co-authored-by: Muhammed Mukhthar CM <[email protected]> * fix(doctor): suppress repeated legacy state migration warnings (openclaw#11709) * fix(doctor): suppress repeated state migration warning * fix: harden state-dir mirror detection + warnings (openclaw#11709) (thanks @gumadeiras) * test: cover mirror hardening edge cases (openclaw#11709) (thanks @gumadeiras) * CI: scope heavy jobs, build once, and remove duplicate validation work (openclaw#11570) * CI: scope jobs and reuse build artifacts * CI: fix scope fallback and remove unused artifact job * CI: remove setup-node pnpm cache inputs * CI: add pnpm store cache and dist artifact smoke * CI: extract pnpm cache action and consume dist artifact * chore: centralizing warning filters * chore: suppress warnings for node default output path * chore: project hygiene — fix workspace:*, sandbox USER, dead config (openclaw#11289) * chore: project hygiene fixes (workspace:*, sandbox USER, dead config) * chore: also fix workspace:* in zalouser dependencies * docs: add security & trust documentation Add threat model (MITRE ATLAS), contribution guide, and security directory README. Update SECURITY.md with trust page reporting instructions and Jamieson O'Reilly as Security & Trust. Co-Authored-By: theonejvo <[email protected]> * Centralize date/time formatting utilities (openclaw#11831) * chore: fix vitest standalone configs and update package description (openclaw#11865) * chore: fix vitest standalone configs and update package description - vitest.live.config.ts and vitest.e2e.config.ts now extend root config - Inherits testTimeout (120s), resolve.alias, pool, setupFiles, excludes - ui/vitest.node.config.ts gets explicit 120s timeout - package.json description updated for multi-channel AI gateway - Removed unused src/utils/time-format.ts * chore: filter inherited excludes in live/e2e vitest configs * refactor: dedupe GroupPolicy/DmPolicy in extensions Import from openclaw/plugin-sdk instead of re-declaring identical types. * Add GitHub Copilot models to xhigh list (openclaw#11646) * Add GitHub Copilot models to xhigh list * fix(thinking): add xhigh copilot tests and changelog (openclaw#11646) (thanks @seans-openclawbot) --------- Co-authored-by: Sean Dai <[email protected]> Co-authored-by: Sebastian <[email protected]> * Exec approvals: render forwarded commands in monospace (openclaw#11937) * fix(exec-approvals): format forwarded commands as code * fix(exec-approvals): place fenced command blocks on new line (openclaw#11937) (thanks @sebslight) * docs: fix changelog PR reference Fix Exec approvals command text formatting issue for safer approval scanning. * Gateway/Plugins: device pairing + phone control plugins (openclaw#11755) * iOS: alpha node app + setup-code onboarding (openclaw#11756) * Memory/QMD: warn when scope denies search * Docs i18n: make translation prompt language-pluggable * Docs: seed ja-JP translations * Docs: use ja-jp Mintlify language code * Docs: note ja-JP docs POC in changelog (openclaw#11988) (thanks @joshp123) * Docs: fix language switcher order + Japanese locale * Docs: note language switcher ordering + JP flag fix (openclaw#12023) (thanks @joshp123) * fix(paths): respect OPENCLAW_HOME for all internal path resolution (openclaw#12091) * fix(paths): respect OPENCLAW_HOME for all internal path resolution (openclaw#11995) Add home-dir module (src/infra/home-dir.ts) that centralizes home directory resolution with precedence: OPENCLAW_HOME > HOME > USERPROFILE > os.homedir(). Migrate all path-sensitive callsites: config IO, agent dirs, session transcripts, pairing store, cron store, doctor, CLI profiles. Add envHomedir() helper in config/paths.ts to reduce lambda noise. Document OPENCLAW_HOME in docs/help/environment.md. * fix(paths): handle OPENCLAW_HOME '~' fallback (openclaw#12091) (thanks @sebslight) * docs: mention OPENCLAW_HOME in install and getting started (openclaw#12091) (thanks @sebslight) * fix(status): show OPENCLAW_HOME in shortened paths (openclaw#12091) (thanks @sebslight) * docs(changelog): clarify OPENCLAW_HOME and HOME precedence (openclaw#12091) (thanks @sebslight) * changelog: split openclaw#12091 entry into Added + Fixes * fix(config): clamp maxTokens to contextWindow to prevent invalid configurations Closes openclaw#5308 When users configure maxTokens larger than contextWindow (e.g., maxTokens: 40960 with contextWindow: 32768), the model may fail silently. This fix clamps maxTokens to be at most contextWindow, preventing such invalid configurations. * test(config): cover maxTokens clamping * chore(changelog): note maxTokens clamp (openclaw#5516) (thanks @lailoo) (openclaw#12139) * fix: more merge fixes * fix: fix gauranteed rejection when declaredCommands undefined * fix: resolve build errors and eslint warnings - Add missing parseDatedFilename function to memory/internal.ts - Remove reference to undefined thinkingWarning variable - Fix node.invoke guard to maintain backward compatibility - Rename unused runtimeConfig variable to _runtimeConfig Co-Authored-By: Claude Sonnet 4.5 <[email protected]> * chore: lancedb embedding/llm-extraction refactoring * Docs: refine LG webOS TV skill (openclaw#360) * Docs: revise PR and issue submission guides (openclaw#10617) * Docs: revise PR submission guide * Docs: revise issue submission guide * docs: fix markdownlint fragments + headings * fix: cron scheduler reliability, store hardening, and UX improvements (openclaw#10776) * refactor: update cron job wake mode and run mode handling - Changed default wake mode from 'next-heartbeat' to 'now' in CronJobEditor and related CLI commands. - Updated cron-tool tests to reflect changes in run mode, introducing 'due' and 'force' options. - Enhanced cron-tool logic to handle new run modes and ensure compatibility with existing job structures. - Added new tests for delivery plan consistency and job execution behavior under various conditions. - Improved normalization functions to handle wake mode and session target casing. This refactor aims to streamline cron job configurations and enhance the overall user experience with clearer defaults and improved functionality. * test: enhance cron job functionality and UI - Added tests to ensure the isolated agent correctly announces the final payload text when delivering messages via Telegram. - Implemented a new function to pick the last deliverable payload from a list of delivery payloads. - Enhanced the cron service to maintain legacy "every" jobs while minute cron jobs recompute schedules. - Updated the cron store migration tests to verify the addition of anchorMs to legacy every schedules. - Improved the UI for displaying cron job details, including job state and delivery information, with new styles and layout adjustments. These changes aim to improve the reliability and user experience of the cron job system. * test: enhance sessions thinking level handling - Added tests to verify that the correct thinking levels are applied during session spawning. - Updated the sessions-spawn-tool to include a new parameter for overriding thinking levels. - Enhanced the UI to support additional thinking levels, including "xhigh" and "full", and improved the handling of current options in dropdowns. These changes aim to improve the flexibility and accuracy of thinking level configurations in session management. * feat: enhance session management and cron job functionality - Introduced passthrough arguments in the test-parallel script to allow for flexible command-line options. - Updated session handling to hide cron run alias session keys from the sessions list, improving clarity. - Enhanced the cron service to accurately record job start times and durations, ensuring better tracking of job execution. - Added tests to verify the correct behavior of the cron service under various conditions, including zero-delay timers. These changes aim to improve the usability and reliability of session and cron job management. * feat: implement job running state checks in cron service - Added functionality to prevent manual job runs if a job is already in progress, enhancing job management. - Updated the `isJobDue` function to include checks for running jobs, ensuring accurate scheduling. - Enhanced the `run` function to return a specific reason when a job is already running. - Introduced a new test case to verify the behavior of forced manual runs during active job execution. These changes aim to improve the reliability and clarity of cron job execution and management. * feat: add session ID and key to CronRunLogEntry model - Introduced `sessionid` and `sessionkey` properties to the `CronRunLogEntry` struct for enhanced tracking of session-related information. - Updated the initializer and Codable conformance to accommodate the new properties, ensuring proper serialization and deserialization. These changes aim to improve the granularity of logging and session management within the cron job system. * fix: improve session display name resolution - Updated the `resolveSessionDisplayName` function to ensure that both label and displayName are trimmed and default to an empty string if not present. - Enhanced the logic to prevent returning the key if it matches the label or displayName, improving clarity in session naming. These changes aim to enhance the accuracy and usability of session display names in the UI. * perf: skip cron store persist when idle timer tick produces no changes recomputeNextRuns now returns a boolean indicating whether any job state was mutated. The idle path in onTimer only persists when the return value is true, eliminating unnecessary file writes every 60s for far-future or idle schedules. * fix: prep for merge - explicit delivery mode migration, docs + changelog (openclaw#10776) (thanks @tyler6204) * fix(memory): add input_type to Voyage AI embeddings for improved retrieval (openclaw#10818) * fix(memory): add input_type to Voyage AI embeddings for improved retrieval Voyage AI recommends passing input_type='document' when indexing and input_type='query' when searching. This improves retrieval quality by optimising the embedding space for each direction. Changes: - embedQuery now passes input_type: 'query' - embedBatch now passes input_type: 'document' - Batch API request_params includes input_type: 'document' - Tests updated to verify input_type is passed correctly * Changelog: note Voyage embeddings input_type fix (openclaw#10818) (thanks @mcinteerj) --------- Co-authored-by: Tak Hoffman <[email protected]> * chore(onboard): move xAI up in auth list * fix: add .caf to AUDIO_FILE_EXTENSIONS (openclaw#10982) * fix: add .caf to AUDIO_FILE_EXTENSIONS for iMessage voice messages * fix: add caf audio extension regression coverage (openclaw#10982) (thanks @succ985) --------- Co-authored-by: succ985 <[email protected]> Co-authored-by: Gustavo Madeira Santana <[email protected]> * feat(gateway): add agents.create/update/delete methods (openclaw#11045) * feat(gateway): add agents.create/update/delete methods * fix(lint): preserve memory-lancedb load error cause * feat(gateway): trash agent files on agents.delete * chore(protocol): regenerate Swift gateway models * fix(gateway): stabilize agents.create dirs and agentDir * feat(gateway): support avatar in agents.create * fix: prep agents.create/update/delete handlers (openclaw#11045) (thanks @advaitpaliwal) - Reuse movePathToTrash from browser/trash.ts (has ~/.Trash fallback on non-macOS) - Fix partial-failure: workspace setup now runs before config write - Always write Name to IDENTITY.md regardless of emoji/avatar - Add unit tests for agents.create, agents.update, agents.delete - Add CHANGELOG entry --------- Co-authored-by: Tyler Yust <[email protected]> * fix(gateway): use LAN IP for WebSocket/probe URLs when bind=lan (openclaw#11448) * fix(gateway): use LAN IP for WebSocket/probe URLs when bind=lan (openclaw#11329) When gateway.bind=lan, the HTTP server correctly binds to 0.0.0.0 (all interfaces), but WebSocket connection URLs, probe targets, and Control UI links were hardcoded to 127.0.0.1. This caused CLI commands and status probes to show localhost-only URLs even in LAN mode, and made onboarding display misleading connection info. - Add pickPrimaryLanIPv4() to gateway/net.ts to detect the machine's primary LAN IPv4 address (prefers en0/eth0, falls back to any external interface) - Update pickProbeHostForBind() to use LAN IP when bind=lan - Update buildGatewayConnectionDetails() to use LAN IP and report "local lan <ip>" as the URL source - Update resolveControlUiLinks() to return LAN-accessible URLs - Update probe note in status.gather.ts to reflect new behavior - Add tests for pickPrimaryLanIPv4 and bind=lan URL resolution Closes openclaw#11329 Co-authored-by: Cursor <[email protected]> * test: move vi.restoreAllMocks to afterEach in pickPrimaryLanIPv4 Per review feedback: avoid calling vi.restoreAllMocks() inside individual tests as it restores all spies globally and can cause ordering issues. Use afterEach in the describe block instead. Co-authored-by: Cursor <[email protected]> * Changelog: note LAN bind URLs fix (openclaw#11448) (thanks @AnonO6) --------- Co-authored-by: Cursor <[email protected]> Co-authored-by: Tak Hoffman <[email protected]> * fix: recover from context overflow caused by oversized tool results (openclaw#11579) * fix: gracefully handle oversized tool results causing context overflow When a subagent reads a very large file or gets a huge tool result (e.g., gh pr diff on a massive PR), it can exceed the model's context window in a single prompt. Auto-compaction can't help because there's no older history to compact — just one giant tool result. This adds two layers of defense: 1. Pre-emptive: Hard cap on tool result size (400K chars ≈ 100K tokens) applied in the session tool result guard before persistence. This prevents extremely large tool results from being stored in full, regardless of model context window size. 2. Recovery: When context overflow is detected and compaction fails, scan session messages for oversized tool results relative to the model's actual context window (30% max share). If found, truncate them in the session via branching (creating a new branch with truncated content) and retry the prompt. The truncation preserves the beginning of the content (most useful for understanding what was read) and appends a notice explaining the truncation and suggesting offset/limit parameters for targeted reads. Includes comprehensive tests for: - Text truncation with newline-boundary awareness - Context-window-proportional size calculation - In-memory message truncation - Oversized detection heuristics - Guard-level size capping during persistence * fix: prep fixes for tool result truncation PR (openclaw#11579) (thanks @tyler6204) * Memory: harden QMD startup, timeouts, and fallback recovery * fix: context overflow compaction and subagent announce improvements (openclaw#11664) (thanks @tyler6204) * initial commit * feat: implement deriveSessionTotalTokens function and update usage tests * Added deriveSessionTotalTokens function to calculate total tokens based on usage and context tokens. * Updated usage tests to include cases for derived session total tokens. * Refactored session usage calculations in multiple files to utilize the new function for improved accuracy. * fix: restore overflow truncation fallback + changelog/test hardening (openclaw#11551) (thanks @tyler6204) * chore: centralizing warning filters * Docs: seed ja-JP translations * Docs: use ja-jp Mintlify language code * Docs: fix language switcher order + Japanese locale * chore: lancedb embedding/llm-extraction refactoring * fix: minor bug in lancedb refactoring --------- Co-authored-by: ideoutrea <[email protected]> Co-authored-by: ide-rea <[email protected]> Co-authored-by: Tak Hoffman <[email protected]> Co-authored-by: Yida-Dev <[email protected]> Co-authored-by: Yida-Dev <[email protected]> Co-authored-by: Claude Opus 4.6 <[email protected]> Co-authored-by: Gustavo Madeira Santana <[email protected]> Co-authored-by: Jake <[email protected]> Co-authored-by: calvin-hpnet <[email protected]> Co-authored-by: Shadril Hassan Shifat <[email protected]> Co-authored-by: Peter Steinberger <[email protected]> Co-authored-by: gitpds <[email protected]> Co-authored-by: Seb Slight <[email protected]> Co-authored-by: Raymond Berger <[email protected]> Co-authored-by: Tyler Yust <[email protected]> Co-authored-by: DEOKLYONG MOON <[email protected]> Co-authored-by: Val Alexander <[email protected]> Co-authored-by: Markus Buhatem Koch <[email protected]> Co-authored-by: Marcus Castro <[email protected]> Co-authored-by: 大猫子 <[email protected]> Co-authored-by: damaozi <[email protected]> Co-authored-by: Tak hoffman <[email protected]> Co-authored-by: quotentiroler <[email protected]> Co-authored-by: Abdullah <[email protected]> Co-authored-by: max <[email protected]> Co-authored-by: succ985 <[email protected]> Co-authored-by: succ985 <[email protected]> Co-authored-by: Advait Paliwal <[email protected]> Co-authored-by: Tyler Yust <[email protected]> Co-authored-by: Aviral <[email protected]> Co-authored-by: Cursor <[email protected]> Co-authored-by: Vignesh Natarajan <[email protected]> Co-authored-by: Gustavo Madeira Santana <[email protected]> Co-authored-by: Rohan Patil <[email protected]> Co-authored-by: danielcadenhead <[email protected]> Co-authored-by: Josh <[email protected]> Co-authored-by: Oleg Kossoy <[email protected]> Co-authored-by: jarvis89757 <[email protected]> Co-authored-by: Shakker <[email protected]> Co-authored-by: ezhikkk <[email protected]> Co-authored-by: Параша <[email protected]> Co-authored-by: Muhammed Mukhthar CM <[email protected]> Co-authored-by: theonejvo <[email protected]> Co-authored-by: seans-openclawbot <[email protected]> Co-authored-by: Sean Dai <[email protected]> Co-authored-by: Mariano Belinky <[email protected]> Co-authored-by: Josh Palmer <[email protected]> Co-authored-by: George Pickett <[email protected]>
* Add baidu qianfan model provider * Add baidu qianfan model provider * Fix format * Optimize doc * optimize doc * Fix import error * Add auth choice * Optimize format * Optimize doc * Fix key resolve * Optimize import * Support ERNIE-5.0-Thinking-Preview * Resolve conflicts * Fix conflicts * Docs: add PR sign-off template (openclaw#10561) * fix: guard resolveUserPath against undefined input (openclaw#10176) * fix: guard resolveUserPath against undefined input When subagent spawner omits workspaceDir, resolveUserPath receives undefined and crashes on .trim(). Add a falsy guard that falls back to process.cwd(), matching the behavior callers already expect. Closes openclaw#10089 Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: harden runner workspace fallback (openclaw#10176) (thanks @Yida-Dev) * fix: harden workspace fallback scoping (openclaw#10176) (thanks @Yida-Dev) * refactor: centralize workspace fallback classification and redaction (openclaw#10176) (thanks @Yida-Dev) * test: remove explicit any from utils mock (openclaw#10176) (thanks @Yida-Dev) * security: reject malformed agent session keys for workspace resolution (openclaw#10176) (thanks @Yida-Dev) --------- Co-authored-by: Yida-Dev <[email protected]> Co-authored-by: Claude Opus 4.6 <[email protected]> Co-authored-by: Gustavo Madeira Santana <[email protected]> * Docs: revise PR and issue submission guides (openclaw#10617) * Docs: revise PR submission guide * Docs: revise issue submission guide * feat(memory): native Voyage AI support (openclaw#7078) * feat(memory): add native Voyage AI embedding support with batching Cherry-picked from PR openclaw#2519, resolved conflict in memory-search.ts (hasRemote -> hasRemoteConfig rename + added voyage provider) * fix(memory): optimize voyage batch memory usage with streaming and deduplicate code Cherry-picked from PR openclaw#2519. Fixed lint error: changed this.runWithConcurrency to use imported runWithConcurrency function after extraction to internal.ts * feat(memory): document Voyage embeddings + VOYAGE_API_KEY (openclaw#7078) (thanks @mcinteerj) (openclaw#10699) * feat(antigravity): update default model to Claude Opus 4.6 (openclaw#10720) * feat(antigravity): update default model to Claude Opus 4.6 Claude Opus 4.5 has been replaced by Claude Opus 4.6 on the Antigravity (Google Cloud Code Assist) platform. - Update DEFAULT_MODEL in google-antigravity-auth extension - Update testing docs to reference the new model * fix: update remaining antigravity opus 4.5 refs in zh-CN docs and tests Address review comments from Greptile: - Update zh-CN/testing.md antigravity model references - Update pi-tools-agent-config.test.ts model IDs * Antigravity: default OAuth model to Opus 4.6 (openclaw#10720) (thanks @calvin-hpnet) --------- Co-authored-by: Tak Hoffman <[email protected]> * fix(hooks): replace debug console.log with proper subsystem logging in session-memory (openclaw#10730) * fix: replace debug console.log with proper subsystem logging in session-memory * fix(hooks): normalize session-memory subsystem logging --------- Co-authored-by: Tak Hoffman <[email protected]> * docs(changelog): prepare 2026.2.6 * docs(changelog): include merged PRs since v2026.2.3 * chore(release): bump version to 2026.2.6 * fix(telegram): cast fetch for grammY ApiClientOptions * docs: fix markdownlint fragments + headings * docs(changelog): refresh 2026.2.6 since v2026.2.3 * docs(imessage): add macOS TCC troubleshooting * docs(imessage): improve macOS TCC troubleshooting guidance (openclaw#10781) * chore(deps): update deps * fix(agents): add Opus 4.6 forward-compat fallback * chore(deps): bump carbon beta * docs(changelog): curate 2026.2.6 * docs(changelog): highlight Opus 4.6 + Codex 5.3 first * Fix QMD CLI installation link in memory.md (openclaw#8647) Correct the installation link for the QMD CLI in the documentation. * chore(lockfile): fix pnpm-lock * fix: cron scheduler reliability, store hardening, and UX improvements (openclaw#10776) * refactor: update cron job wake mode and run mode handling - Changed default wake mode from 'next-heartbeat' to 'now' in CronJobEditor and related CLI commands. - Updated cron-tool tests to reflect changes in run mode, introducing 'due' and 'force' options. - Enhanced cron-tool logic to handle new run modes and ensure compatibility with existing job structures. - Added new tests for delivery plan consistency and job execution behavior under various conditions. - Improved normalization functions to handle wake mode and session target casing. This refactor aims to streamline cron job configurations and enhance the overall user experience with clearer defaults and improved functionality. * test: enhance cron job functionality and UI - Added tests to ensure the isolated agent correctly announces the final payload text when delivering messages via Telegram. - Implemented a new function to pick the last deliverable payload from a list of delivery payloads. - Enhanced the cron service to maintain legacy "every" jobs while minute cron jobs recompute schedules. - Updated the cron store migration tests to verify the addition of anchorMs to legacy every schedules. - Improved the UI for displaying cron job details, including job state and delivery information, with new styles and layout adjustments. These changes aim to improve the reliability and user experience of the cron job system. * test: enhance sessions thinking level handling - Added tests to verify that the correct thinking levels are applied during session spawning. - Updated the sessions-spawn-tool to include a new parameter for overriding thinking levels. - Enhanced the UI to support additional thinking levels, including "xhigh" and "full", and improved the handling of current options in dropdowns. These changes aim to improve the flexibility and accuracy of thinking level configurations in session management. * feat: enhance session management and cron job functionality - Introduced passthrough arguments in the test-parallel script to allow for flexible command-line options. - Updated session handling to hide cron run alias session keys from the sessions list, improving clarity. - Enhanced the cron service to accurately record job start times and durations, ensuring better tracking of job execution. - Added tests to verify the correct behavior of the cron service under various conditions, including zero-delay timers. These changes aim to improve the usability and reliability of session and cron job management. * feat: implement job running state checks in cron service - Added functionality to prevent manual job runs if a job is already in progress, enhancing job management. - Updated the `isJobDue` function to include checks for running jobs, ensuring accurate scheduling. - Enhanced the `run` function to return a specific reason when a job is already running. - Introduced a new test case to verify the behavior of forced manual runs during active job execution. These changes aim to improve the reliability and clarity of cron job execution and management. * feat: add session ID and key to CronRunLogEntry model - Introduced `sessionid` and `sessionkey` properties to the `CronRunLogEntry` struct for enhanced tracking of session-related information. - Updated the initializer and Codable conformance to accommodate the new properties, ensuring proper serialization and deserialization. These changes aim to improve the granularity of logging and session management within the cron job system. * fix: improve session display name resolution - Updated the `resolveSessionDisplayName` function to ensure that both label and displayName are trimmed and default to an empty string if not present. - Enhanced the logic to prevent returning the key if it matches the label or displayName, improving clarity in session naming. These changes aim to enhance the accuracy and usability of session display names in the UI. * perf: skip cron store persist when idle timer tick produces no changes recomputeNextRuns now returns a boolean indicating whether any job state was mutated. The idle path in onTimer only persists when the return value is true, eliminating unnecessary file writes every 60s for far-future or idle schedules. * fix: prep for merge - explicit delivery mode migration, docs + changelog (openclaw#10776) (thanks @tyler6204) * Docs: fix broken /plugins links (openclaw#9308) * Docs: fix broken /plugins links to /plugin The documentation linked to /plugins which doesn't exist. The correct path is /plugin (singular) which contains the plugins overview documentation. Co-Authored-By: Claude Opus 4.5 <[email protected]> * docs: drop manual zh-CN doc edits from plugins link fix --------- Co-authored-by: Claude Opus 4.5 <[email protected]> Co-authored-by: Sebastian <[email protected]> * fix(build): unblock pnpm build dts * Fix repository links in formal-verification.md (openclaw#10200) Updated repository links for formal verification models. * Revert previous change from 'Clawdbot' to 'OpenClaw' in lore (openclaw#9119) * fix(memory): add input_type to Voyage AI embeddings for improved retrieval (openclaw#10818) * fix(memory): add input_type to Voyage AI embeddings for improved retrieval Voyage AI recommends passing input_type='document' when indexing and input_type='query' when searching. This improves retrieval quality by optimising the embedding space for each direction. Changes: - embedQuery now passes input_type: 'query' - embedBatch now passes input_type: 'document' - Batch API request_params includes input_type: 'document' - Tests updated to verify input_type is passed correctly * Changelog: note Voyage embeddings input_type fix (openclaw#10818) (thanks @mcinteerj) --------- Co-authored-by: Tak Hoffman <[email protected]> * fix(dashboard): restore tokenized control ui links * chore(skills): remove bird skill * chore(onboard): move xAI up in auth list * chore(release): 2026.2.6-1 * chore(onboard): move xAI below Google * ci: add concurrency controls, consolidate macOS jobs, optimize Windows CI * ci: re-enable parallel vitest on Windows CI * docs(changelog): note CI pipeline optimization (openclaw#10784) (thanks @mcaxtr) * fix(build): support daemon-cli .mjs bundles in compat shim * fix(docker): support .mjs entrypoints in images and e2e * test(hooks): stabilize session-memory hook tests * chore(release): 2026.2.6-2 * chore(onboard): reorder xAI + Qianfan providers * chore(release): 2026.2.6-3 * fix: comprehensive BlueBubbles and channel cleanup (openclaw#11093) * feat(bluebubbles): auto-strip markdown from outbound messages (openclaw#7402) * fix(security): add timeout to webhook body reading (openclaw#6762) Adds 30-second timeout to readBody() in voice-call, bluebubbles, and nostr webhook handlers. Prevents Slow-Loris DoS (CWE-400, CVSS 7.5). Merged with existing maxBytes protection in voice-call. * fix(security): unify Error objects and lint fixes in webhook timeouts (openclaw#6762) * fix: prevent plugins from auto-enabling without user consent (openclaw#3961) Changes default plugin enabled state from true to false in enablePluginEntry(). Preserves existing enabled:true values. Fixes openclaw#3932. * fix: apply hierarchical mediaMaxMb config to all channels (openclaw#8749) Generalizes resolveAttachmentMaxBytes() to use account → channel → global config resolution for all channels, not just BlueBubbles. Fixes openclaw#7847. * fix(bluebubbles): sanitize attachment filenames against header injection (openclaw#10333) Strip ", \r, \n, and \\ from filenames after path.basename() to prevent multipart Content-Disposition header injection (CWE-93, CVSS 5.4). Also adds sanitization to setGroupIconBlueBubbles which had zero filename sanitization. * fix(lint): exclude extensions/ from Oxlint preflight check (openclaw#9313) Extensions use PluginRuntime|null patterns that trigger no-redundant-type-constituents because PluginRuntime resolves to any. Excluding extensions/ from Oxlint unblocks user upgrades. Re-applies the approach from closed PR openclaw#10087. * fix(bluebubbles): add tempGuid to createNewChatWithMessage payload (openclaw#7745) Non-Private-API mode (AppleScript) requires tempGuid in send payloads. The main sendMessageBlueBubbles already had it, but createNewChatWithMessage was missing it, causing 400 errors for new chat creation without Private API. * fix: send stop-typing signal when run ends with NO_REPLY (openclaw#8785) Adds onCleanup callback to the typing controller that fires when the controller is cleaned up while typing was active (e.g., after NO_REPLY). Channels using createTypingCallbacks automatically get stop-typing on cleanup. This prevents the typing indicator from lingering in group chats when the agent decides not to reply. * fix(telegram): deduplicate skill commands in multi-agent setup (openclaw#5717) Two fixes: 1. Skip duplicate workspace dirs when listing skill commands across agents. Multiple agents sharing the same workspace would produce duplicate commands with _2, _3 suffixes. 2. Clear stale commands via deleteMyCommands before registering new ones. Commands from deleted skills now get cleaned up on restart. * fix: add size limits to unbounded in-memory caches (openclaw#4948) Adds max-size caps with oldest-entry eviction to prevent OOM in long-running deployments: - BlueBubbles serverInfoCache: 64 entries (already has TTL) - Google Chat authCache: 32 entries - Matrix directRoomCache: 1024 entries - Discord presenceCache: 5000 entries per account * fix: address review concerns (openclaw#11093) - Chain deleteMyCommands → setMyCommands to prevent race condition (openclaw#5717) - Rename enablePluginEntry to registerPluginEntry (now sets enabled: false) - Add Slow-Loris timeout test for readJsonBody (openclaw#6023) * docs: add symptom-first troubleshooting hub and deep runbooks (openclaw#11196) * docs(troubleshooting): add symptom-first troubleshooting runbooks * docs(troubleshooting): fix approvals command examples * docs(troubleshooting): wrap symptom cases in accordions * docs(automation): clarify userTimezone missing-key behavior * docs(troubleshooting): fix first-60-seconds ladder order * docs: add missing HEARTBEAT.md and MEMORY.md to bootstrap files list (openclaw#8105) * docs: add missing HEARTBEAT.md and MEMORY.md to bootstrap files list Fixes openclaw#7928 The documentation for skipBootstrap and workspace setup was missing HEARTBEAT.md and MEMORY.md from the bootstrap files list. Changes: - docs/gateway/configuration.md: Add HEARTBEAT.md and MEMORY.md - docs/zh-CN/gateway/configuration.md: Same for Chinese version - docs/start/openclaw.md: Add HEARTBEAT.md, clarify MEMORY.md is optional - docs/zh-CN/start/openclaw.md: Same for Chinese version * fix: reference PR number instead of issue in CHANGELOG * docs(workspace): align bootstrap file docs with runtime (openclaw#8105) --------- Co-authored-by: damaozi <[email protected]> Co-authored-by: Sebastian <[email protected]> * Agents: include runtime shell (openclaw#1835) * Agents: include runtime shell * Agents: fix compact runtime build * chore: fix CLAUDE.md formatting, security regex for secret --------- Co-authored-by: Tak hoffman <[email protected]> Co-authored-by: quotentiroler <[email protected]> * Web UI: show Compaction divider in chat history (openclaw#11341) * adding PR review workflow * added more explicit instructions * docs: canonicalize docs paths and align zh navigation (openclaw#11428) * docs(navigation): canonicalize paths and align zh nav * chore(docs): remove stray .DS_Store * docs(scripts): add non-mint docs link audit * docs(nav): fix zh source paths and preserve legacy redirects (openclaw#11428) (thanks @sebslight) * chore(docs): satisfy lint for docs link audit script (openclaw#11428) (thanks @sebslight) * chore: bump pi to 0.52.8 * Fix typo in FAQ regarding model configuration command (openclaw#6048) * CI: skip heavy jobs on docs-only changes (openclaw#11328) * fix: add .caf to AUDIO_FILE_EXTENSIONS (openclaw#10982) * fix: add .caf to AUDIO_FILE_EXTENSIONS for iMessage voice messages * fix: add caf audio extension regression coverage (openclaw#10982) (thanks @succ985) --------- Co-authored-by: succ985 <[email protected]> Co-authored-by: Gustavo Madeira Santana <[email protected]> * Gateway: fix multi-agent sessions.usage discovery (openclaw#11523) * Gateway: fix multi-agent sessions.usage discovery * Gateway: resolve sessions.usage keys via sessionId * feat(gateway): add agents.create/update/delete methods (openclaw#11045) * feat(gateway): add agents.create/update/delete methods * fix(lint): preserve memory-lancedb load error cause * feat(gateway): trash agent files on agents.delete * chore(protocol): regenerate Swift gateway models * fix(gateway): stabilize agents.create dirs and agentDir * feat(gateway): support avatar in agents.create * fix: prep agents.create/update/delete handlers (openclaw#11045) (thanks @advaitpaliwal) - Reuse movePathToTrash from browser/trash.ts (has ~/.Trash fallback on non-macOS) - Fix partial-failure: workspace setup now runs before config write - Always write Name to IDENTITY.md regardless of emoji/avatar - Add unit tests for agents.create, agents.update, agents.delete - Add CHANGELOG entry --------- Co-authored-by: Tyler Yust <[email protected]> * feat(sanitize): enhance context overflow error handling in user-facing text - Added tests to ensure proper sanitization of context overflow errors. - Introduced a new function to determine when to rewrite context overflow messages. - Updated the sanitization logic to improve user experience by providing clearer error messages while preserving conversational context. * fix(gateway): use LAN IP for WebSocket/probe URLs when bind=lan (openclaw#11448) * fix(gateway): use LAN IP for WebSocket/probe URLs when bind=lan (openclaw#11329) When gateway.bind=lan, the HTTP server correctly binds to 0.0.0.0 (all interfaces), but WebSocket connection URLs, probe targets, and Control UI links were hardcoded to 127.0.0.1. This caused CLI commands and status probes to show localhost-only URLs even in LAN mode, and made onboarding display misleading connection info. - Add pickPrimaryLanIPv4() to gateway/net.ts to detect the machine's primary LAN IPv4 address (prefers en0/eth0, falls back to any external interface) - Update pickProbeHostForBind() to use LAN IP when bind=lan - Update buildGatewayConnectionDetails() to use LAN IP and report "local lan <ip>" as the URL source - Update resolveControlUiLinks() to return LAN-accessible URLs - Update probe note in status.gather.ts to reflect new behavior - Add tests for pickPrimaryLanIPv4 and bind=lan URL resolution Closes openclaw#11329 Co-authored-by: Cursor <[email protected]> * test: move vi.restoreAllMocks to afterEach in pickPrimaryLanIPv4 Per review feedback: avoid calling vi.restoreAllMocks() inside individual tests as it restores all spies globally and can cause ordering issues. Use afterEach in the describe block instead. Co-authored-by: Cursor <[email protected]> * Changelog: note LAN bind URLs fix (openclaw#11448) (thanks @AnonO6) --------- Co-authored-by: Cursor <[email protected]> Co-authored-by: Tak Hoffman <[email protected]> * fix: recover from context overflow caused by oversized tool results (openclaw#11579) * fix: gracefully handle oversized tool results causing context overflow When a subagent reads a very large file or gets a huge tool result (e.g., gh pr diff on a massive PR), it can exceed the model's context window in a single prompt. Auto-compaction can't help because there's no older history to compact — just one giant tool result. This adds two layers of defense: 1. Pre-emptive: Hard cap on tool result size (400K chars ≈ 100K tokens) applied in the session tool result guard before persistence. This prevents extremely large tool results from being stored in full, regardless of model context window size. 2. Recovery: When context overflow is detected and compaction fails, scan session messages for oversized tool results relative to the model's actual context window (30% max share). If found, truncate them in the session via branching (creating a new branch with truncated content) and retry the prompt. The truncation preserves the beginning of the content (most useful for understanding what was read) and appends a notice explaining the truncation and suggesting offset/limit parameters for targeted reads. Includes comprehensive tests for: - Text truncation with newline-boundary awareness - Context-window-proportional size calculation - In-memory message truncation - Oversized detection heuristics - Guard-level size capping during persistence * fix: prep fixes for tool result truncation PR (openclaw#11579) (thanks @tyler6204) * Memory: harden QMD startup, timeouts, and fallback recovery * Memory: queue forced QMD sync and handle sqlite busy reads * Memory: chain forced QMD queue and fail over on busy index * Memory: make QMD cache eviction callback idempotent * Memory: add SQLITE_BUSY fallback regression test * Update CHANGELOG.md for version 2026.2.6-4: Added RPC methods for agent management, fixed context overflow recovery, improved LAN IP handling, enhanced memory retrieval, and updated media understanding for audio transcription. * Tests: harden flake hotspots and consolidate provider-auth suites (openclaw#11598) * Tests: harden flake hotspots and consolidate provider-auth suites * Tests: restore env vars by deleting missing snapshot values * Tests: use real newline in memory summary filter case * Tests(memory): use fake timers for qmd timeout coverage * Changelog: add tests hardening entry for openclaw#11598 * docs: clarify onboarding instructions for beginners (openclaw#10956) * chore: updated PR review skills and workflow info on tests + fake timers * Fix Nix repository link in README (openclaw#7910) Updated Nix repository link in README. Co-authored-by: Josh <[email protected]> Co-authored-by: Seb Slight <[email protected]> * Docs: fix cron.update param name id → jobId (openclaw#11365) (openclaw#11467) * Docs: fix cron.update param name id → jobId (openclaw#11365) * Docs: sync zh-CN cron.update param name id → jobId * docs: revert manual zh-CN generated docs edit (openclaw#11467) (thanks @lailoo) --------- Co-authored-by: damaozi <[email protected]> Co-authored-by: Sebastian <[email protected]> * fix: use STATE_DIR instead of hardcoded ~/.openclaw for identity and canvas (openclaw#4824) * fix: use STATE_DIR instead of hardcoded ~/.openclaw for identity and canvas device-identity.ts and canvas-host/server.ts used hardcoded path.join(os.homedir(), '.openclaw', ...) ignoring OPENCLAW_STATE_DIR env var and the resolveStateDir() logic from config/paths.ts. This caused ~/.openclaw/identity and ~/.openclaw/canvas directories to be created even when state dir was overridden or resided elsewhere. * fix: format and remove duplicate imports * fix: scope state-dir patch + add regression tests (openclaw#4824) (thanks @kossoy) * fix: align state-dir fallbacks in hooks and agent paths (openclaw#4824) (thanks @kossoy) --------- Co-authored-by: Gustavo Madeira Santana <[email protected]> * fix(cron): share isolated announce flow + harden cron scheduling/delivery (openclaw#11641) * fix(cron): comprehensive cron scheduling and delivery fixes - Fix delivery target resolution for isolated agent cron jobs - Improve schedule parsing and validation - Add job retry logic and error handling - Enhance cron ops with better state management - Add timer improvements for more reliable cron execution - Add cron event type to protocol schema - Support cron events in heartbeat runner (skip empty-heartbeat check, use dedicated CRON_EVENT_PROMPT for relay) * fix: remove cron debug test and add changelog/docs notes (openclaw#11641) (thanks @tyler6204) * fix: context overflow compaction and subagent announce improvements (openclaw#11664) (thanks @tyler6204) * initial commit * feat: implement deriveSessionTotalTokens function and update usage tests * Added deriveSessionTotalTokens function to calculate total tokens based on usage and context tokens. * Updated usage tests to include cases for derived session total tokens. * Refactored session usage calculations in multiple files to utilize the new function for improved accuracy. * fix: restore overflow truncation fallback + changelog/test hardening (openclaw#11551) (thanks @tyler6204) * fix(ui): smooth chat refresh scroll and suppress new-messages badge flash * fix(discord): support forum channel thread-create (openclaw#10062) * fix(discord): support forum channel thread-create * fix: harden discord forum thread-create (openclaw#10062) (thanks @jarvis89757) --------- Co-authored-by: Shakker <[email protected]> * feat(telegram): add spoiler tag support (openclaw#11543) * feat(telegram): add spoiler tag support Render markdown ||spoiler|| syntax as <tg-spoiler> tags in Telegram HTML output. The markdown IR already parses spoiler syntax, but the Telegram renderer was missing the style marker. This adds the spoiler marker to renderTelegramHtml(). Fixes spoiler text appearing as raw ||text|| instead of hidden text. * fix: enable Telegram spoiler rendering (openclaw#11543) (thanks @ezhikkk) --------- Co-authored-by: Параша <[email protected]> Co-authored-by: Muhammed Mukhthar CM <[email protected]> * fix(doctor): suppress repeated legacy state migration warnings (openclaw#11709) * fix(doctor): suppress repeated state migration warning * fix: harden state-dir mirror detection + warnings (openclaw#11709) (thanks @gumadeiras) * test: cover mirror hardening edge cases (openclaw#11709) (thanks @gumadeiras) * CI: scope heavy jobs, build once, and remove duplicate validation work (openclaw#11570) * CI: scope jobs and reuse build artifacts * CI: fix scope fallback and remove unused artifact job * CI: remove setup-node pnpm cache inputs * CI: add pnpm store cache and dist artifact smoke * CI: extract pnpm cache action and consume dist artifact * chore: centralizing warning filters * chore: suppress warnings for node default output path * chore: project hygiene — fix workspace:*, sandbox USER, dead config (openclaw#11289) * chore: project hygiene fixes (workspace:*, sandbox USER, dead config) * chore: also fix workspace:* in zalouser dependencies * docs: add security & trust documentation Add threat model (MITRE ATLAS), contribution guide, and security directory README. Update SECURITY.md with trust page reporting instructions and Jamieson O'Reilly as Security & Trust. Co-Authored-By: theonejvo <[email protected]> * Centralize date/time formatting utilities (openclaw#11831) * chore: fix vitest standalone configs and update package description (openclaw#11865) * chore: fix vitest standalone configs and update package description - vitest.live.config.ts and vitest.e2e.config.ts now extend root config - Inherits testTimeout (120s), resolve.alias, pool, setupFiles, excludes - ui/vitest.node.config.ts gets explicit 120s timeout - package.json description updated for multi-channel AI gateway - Removed unused src/utils/time-format.ts * chore: filter inherited excludes in live/e2e vitest configs * refactor: dedupe GroupPolicy/DmPolicy in extensions Import from openclaw/plugin-sdk instead of re-declaring identical types. * Add GitHub Copilot models to xhigh list (openclaw#11646) * Add GitHub Copilot models to xhigh list * fix(thinking): add xhigh copilot tests and changelog (openclaw#11646) (thanks @seans-openclawbot) --------- Co-authored-by: Sean Dai <[email protected]> Co-authored-by: Sebastian <[email protected]> * Exec approvals: render forwarded commands in monospace (openclaw#11937) * fix(exec-approvals): format forwarded commands as code * fix(exec-approvals): place fenced command blocks on new line (openclaw#11937) (thanks @sebslight) * docs: fix changelog PR reference Fix Exec approvals command text formatting issue for safer approval scanning. * Gateway/Plugins: device pairing + phone control plugins (openclaw#11755) * iOS: alpha node app + setup-code onboarding (openclaw#11756) * Memory/QMD: warn when scope denies search * Docs i18n: make translation prompt language-pluggable * Docs: seed ja-JP translations * Docs: use ja-jp Mintlify language code * Docs: note ja-JP docs POC in changelog (openclaw#11988) (thanks @joshp123) * Docs: fix language switcher order + Japanese locale * Docs: note language switcher ordering + JP flag fix (openclaw#12023) (thanks @joshp123) * fix(paths): respect OPENCLAW_HOME for all internal path resolution (openclaw#12091) * fix(paths): respect OPENCLAW_HOME for all internal path resolution (openclaw#11995) Add home-dir module (src/infra/home-dir.ts) that centralizes home directory resolution with precedence: OPENCLAW_HOME > HOME > USERPROFILE > os.homedir(). Migrate all path-sensitive callsites: config IO, agent dirs, session transcripts, pairing store, cron store, doctor, CLI profiles. Add envHomedir() helper in config/paths.ts to reduce lambda noise. Document OPENCLAW_HOME in docs/help/environment.md. * fix(paths): handle OPENCLAW_HOME '~' fallback (openclaw#12091) (thanks @sebslight) * docs: mention OPENCLAW_HOME in install and getting started (openclaw#12091) (thanks @sebslight) * fix(status): show OPENCLAW_HOME in shortened paths (openclaw#12091) (thanks @sebslight) * docs(changelog): clarify OPENCLAW_HOME and HOME precedence (openclaw#12091) (thanks @sebslight) * changelog: split openclaw#12091 entry into Added + Fixes * fix(config): clamp maxTokens to contextWindow to prevent invalid configurations Closes openclaw#5308 When users configure maxTokens larger than contextWindow (e.g., maxTokens: 40960 with contextWindow: 32768), the model may fail silently. This fix clamps maxTokens to be at most contextWindow, preventing such invalid configurations. * test(config): cover maxTokens clamping * chore(changelog): note maxTokens clamp (openclaw#5516) (thanks @lailoo) (openclaw#12139) * fix: more merge fixes * fix: fix gauranteed rejection when declaredCommands undefined * fix: resolve build errors and eslint warnings - Add missing parseDatedFilename function to memory/internal.ts - Remove reference to undefined thinkingWarning variable - Fix node.invoke guard to maintain backward compatibility - Rename unused runtimeConfig variable to _runtimeConfig Co-Authored-By: Claude Sonnet 4.5 <[email protected]> * chore: lancedb embedding/llm-extraction refactoring * Docs: revise PR and issue submission guides (openclaw#10617) * Docs: revise PR submission guide * Docs: revise issue submission guide * docs: fix markdownlint fragments + headings * fix: cron scheduler reliability, store hardening, and UX improvements (openclaw#10776) * refactor: update cron job wake mode and run mode handling - Changed default wake mode from 'next-heartbeat' to 'now' in CronJobEditor and related CLI commands. - Updated cron-tool tests to reflect changes in run mode, introducing 'due' and 'force' options. - Enhanced cron-tool logic to handle new run modes and ensure compatibility with existing job structures. - Added new tests for delivery plan consistency and job execution behavior under various conditions. - Improved normalization functions to handle wake mode and session target casing. This refactor aims to streamline cron job configurations and enhance the overall user experience with clearer defaults and improved functionality. * test: enhance cron job functionality and UI - Added tests to ensure the isolated agent correctly announces the final payload text when delivering messages via Telegram. - Implemented a new function to pick the last deliverable payload from a list of delivery payloads. - Enhanced the cron service to maintain legacy "every" jobs while minute cron jobs recompute schedules. - Updated the cron store migration tests to verify the addition of anchorMs to legacy every schedules. - Improved the UI for displaying cron job details, including job state and delivery information, with new styles and layout adjustments. These changes aim to improve the reliability and user experience of the cron job system. * test: enhance sessions thinking level handling - Added tests to verify that the correct thinking levels are applied during session spawning. - Updated the sessions-spawn-tool to include a new parameter for overriding thinking levels. - Enhanced the UI to support additional thinking levels, including "xhigh" and "full", and improved the handling of current options in dropdowns. These changes aim to improve the flexibility and accuracy of thinking level configurations in session management. * feat: enhance session management and cron job functionality - Introduced passthrough arguments in the test-parallel script to allow for flexible command-line options. - Updated session handling to hide cron run alias session keys from the sessions list, improving clarity. - Enhanced the cron service to accurately record job start times and durations, ensuring better tracking of job execution. - Added tests to verify the correct behavior of the cron service under various conditions, including zero-delay timers. These changes aim to improve the usability and reliability of session and cron job management. * feat: implement job running state checks in cron service - Added functionality to prevent manual job runs if a job is already in progress, enhancing job management. - Updated the `isJobDue` function to include checks for running jobs, ensuring accurate scheduling. - Enhanced the `run` function to return a specific reason when a job is already running. - Introduced a new test case to verify the behavior of forced manual runs during active job execution. These changes aim to improve the reliability and clarity of cron job execution and management. * feat: add session ID and key to CronRunLogEntry model - Introduced `sessionid` and `sessionkey` properties to the `CronRunLogEntry` struct for enhanced tracking of session-related information. - Updated the initializer and Codable conformance to accommodate the new properties, ensuring proper serialization and deserialization. These changes aim to improve the granularity of logging and session management within the cron job system. * fix: improve session display name resolution - Updated the `resolveSessionDisplayName` function to ensure that both label and displayName are trimmed and default to an empty string if not present. - Enhanced the logic to prevent returning the key if it matches the label or displayName, improving clarity in session naming. These changes aim to enhance the accuracy and usability of session display names in the UI. * perf: skip cron store persist when idle timer tick produces no changes recomputeNextRuns now returns a boolean indicating whether any job state was mutated. The idle path in onTimer only persists when the return value is true, eliminating unnecessary file writes every 60s for far-future or idle schedules. * fix: prep for merge - explicit delivery mode migration, docs + changelog (openclaw#10776) (thanks @tyler6204) * fix(memory): add input_type to Voyage AI embeddings for improved retrieval (openclaw#10818) * fix(memory): add input_type to Voyage AI embeddings for improved retrieval Voyage AI recommends passing input_type='document' when indexing and input_type='query' when searching. This improves retrieval quality by optimising the embedding space for each direction. Changes: - embedQuery now passes input_type: 'query' - embedBatch now passes input_type: 'document' - Batch API request_params includes input_type: 'document' - Tests updated to verify input_type is passed correctly * Changelog: note Voyage embeddings input_type fix (openclaw#10818) (thanks @mcinteerj) --------- Co-authored-by: Tak Hoffman <[email protected]> * chore(onboard): move xAI up in auth list * fix: add .caf to AUDIO_FILE_EXTENSIONS (openclaw#10982) * fix: add .caf to AUDIO_FILE_EXTENSIONS for iMessage voice messages * fix: add caf audio extension regression coverage (openclaw#10982) (thanks @succ985) --------- Co-authored-by: succ985 <[email protected]> Co-authored-by: Gustavo Madeira Santana <[email protected]> * feat(gateway): add agents.create/update/delete methods (openclaw#11045) * feat(gateway): add agents.create/update/delete methods * fix(lint): preserve memory-lancedb load error cause * feat(gateway): trash agent files on agents.delete * chore(protocol): regenerate Swift gateway models * fix(gateway): stabilize agents.create dirs and agentDir * feat(gateway): support avatar in agents.create * fix: prep agents.create/update/delete handlers (openclaw#11045) (thanks @advaitpaliwal) - Reuse movePathToTrash from browser/trash.ts (has ~/.Trash fallback on non-macOS) - Fix partial-failure: workspace setup now runs before config write - Always write Name to IDENTITY.md regardless of emoji/avatar - Add unit tests for agents.create, agents.update, agents.delete - Add CHANGELOG entry --------- Co-authored-by: Tyler Yust <[email protected]> * fix(gateway): use LAN IP for WebSocket/probe URLs when bind=lan (openclaw#11448) * fix(gateway): use LAN IP for WebSocket/probe URLs when bind=lan (openclaw#11329) When gateway.bind=lan, the HTTP server correctly binds to 0.0.0.0 (all interfaces), but WebSocket connection URLs, probe targets, and Control UI links were hardcoded to 127.0.0.1. This caused CLI commands and status probes to show localhost-only URLs even in LAN mode, and made onboarding display misleading connection info. - Add pickPrimaryLanIPv4() to gateway/net.ts to detect the machine's primary LAN IPv4 address (prefers en0/eth0, falls back to any external interface) - Update pickProbeHostForBind() to use LAN IP when bind=lan - Update buildGatewayConnectionDetails() to use LAN IP and report "local lan <ip>" as the URL source - Update resolveControlUiLinks() to return LAN-accessible URLs - Update probe note in status.gather.ts to reflect new behavior - Add tests for pickPrimaryLanIPv4 and bind=lan URL resolution Closes openclaw#11329 Co-authored-by: Cursor <[email protected]> * test: move vi.restoreAllMocks to afterEach in pickPrimaryLanIPv4 Per review feedback: avoid calling vi.restoreAllMocks() inside individual tests as it restores all spies globally and can cause ordering issues. Use afterEach in the describe block instead. Co-authored-by: Cursor <[email protected]> * Changelog: note LAN bind URLs fix (openclaw#11448) (thanks @AnonO6) --------- Co-authored-by: Cursor <[email protected]> Co-authored-by: Tak Hoffman <[email protected]> * fix: recover from context overflow caused by oversized tool results (openclaw#11579) * fix: gracefully handle oversized tool results causing context overflow When a subagent reads a very large file or gets a huge tool result (e.g., gh pr diff on a massive PR), it can exceed the model's context window in a single prompt. Auto-compaction can't help because there's no older history to compact — just one giant tool result. This adds two layers of defense: 1. Pre-emptive: Hard cap on tool result size (400K chars ≈ 100K tokens) applied in the session tool result guard before persistence. This prevents extremely large tool results from being stored in full, regardless of model context window size. 2. Recovery: When context overflow is detected and compaction fails, scan session messages for oversized tool results relative to the model's actual context window (30% max share). If found, truncate them in the session via branching (creating a new branch with truncated content) and retry the prompt. The truncation preserves the beginning of the content (most useful for understanding what was read) and appends a notice explaining the truncation and suggesting offset/limit parameters for targeted reads. Includes comprehensive tests for: - Text truncation with newline-boundary awareness - Context-window-proportional size calculation - In-memory message truncation - Oversized detection heuristics - Guard-level size capping during persistence * fix: prep fixes for tool result truncation PR (openclaw#11579) (thanks @tyler6204) * Memory: harden QMD startup, timeouts, and fallback recovery * fix: context overflow compaction and subagent announce improvements (openclaw#11664) (thanks @tyler6204) * initial commit * feat: implement deriveSessionTotalTokens function and update usage tests * Added deriveSessionTotalTokens function to calculate total tokens based on usage and context tokens. * Updated usage tests to include cases for derived session total tokens. * Refactored session usage calculations in multiple files to utilize the new function for improved accuracy. * fix: restore overflow truncation fallback + changelog/test hardening (openclaw#11551) (thanks @tyler6204) * chore: centralizing warning filters * Docs: seed ja-JP translations * Docs: use ja-jp Mintlify language code * Docs: fix language switcher order + Japanese locale * chore: lancedb embedding/llm-extraction refactoring * fix: minor bug in lancedb refactoring * additional test fixes * crap loads of lint fixes * fix: restore nullish fallback for context.outputs spread in worker.ts When context is undefined or lacks an outputs object, spreading ...context?.outputs can throw TypeError in some transpilation targets. Restores the previous ...(context?.outputs ?? {}) guard. Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: guard against undefined context.outputs spread in worker.ts Extract context?.outputs into a temp variable with ?? {} fallback before spreading, avoiding potential TypeError when context or its outputs property is undefined. Uses a temp variable instead of inline ?? {} to prevent oxfmt from stripping the guard. Co-Authored-By: Claude Opus 4.6 <[email protected]> --------- Co-authored-by: ideoutrea <[email protected]> Co-authored-by: ide-rea <[email protected]> Co-authored-by: Tak Hoffman <[email protected]> Co-authored-by: Yida-Dev <[email protected]> Co-authored-by: Yida-Dev <[email protected]> Co-authored-by: Claude Opus 4.6 <[email protected]> Co-authored-by: Gustavo Madeira Santana <[email protected]> Co-authored-by: Jake <[email protected]> Co-authored-by: calvin-hpnet <[email protected]> Co-authored-by: Shadril Hassan Shifat <[email protected]> Co-authored-by: Peter Steinberger <[email protected]> Co-authored-by: gitpds <[email protected]> Co-authored-by: Seb Slight <[email protected]> Co-authored-by: Raymond Berger <[email protected]> Co-authored-by: Tyler Yust <[email protected]> Co-authored-by: DEOKLYONG MOON <[email protected]> Co-authored-by: Val Alexander <[email protected]> Co-authored-by: Markus Buhatem Koch <[email protected]> Co-authored-by: Marcus Castro <[email protected]> Co-authored-by: 大猫子 <[email protected]> Co-authored-by: damaozi <[email protected]> Co-authored-by: Tak hoffman <[email protected]> Co-authored-by: quotentiroler <[email protected]> Co-authored-by: Abdullah <[email protected]> Co-authored-by: max <[email protected]> Co-authored-by: succ985 <[email protected]> Co-authored-by: succ985 <[email protected]> Co-authored-by: Advait Paliwal <[email protected]> Co-authored-by: Tyler Yust <[email protected]> Co-authored-by: Aviral <[email protected]> Co-authored-by: Cursor <[email protected]> Co-authored-by: Vignesh Natarajan <[email protected]> Co-authored-by: Gustavo Madeira Santana <[email protected]> Co-authored-by: Rohan Patil <[email protected]> Co-authored-by: danielcadenhead <[email protected]> Co-authored-by: Josh <[email protected]> Co-authored-by: Oleg Kossoy <[email protected]> Co-authored-by: jarvis89757 <[email protected]> Co-authored-by: Shakker <[email protected]> Co-authored-by: ezhikkk <[email protected]> Co-authored-by: Параша <[email protected]> Co-authored-by: Muhammed Mukhthar CM <[email protected]> Co-authored-by: theonejvo <[email protected]> Co-authored-by: seans-openclawbot <[email protected]> Co-authored-by: Sean Dai <[email protected]> Co-authored-by: Mariano Belinky <[email protected]> Co-authored-by: Josh Palmer <[email protected]> Co-authored-by: George Pickett <[email protected]>
…law#11709) * fix(doctor): suppress repeated state migration warning * fix: harden state-dir mirror detection + warnings (openclaw#11709) (thanks @gumadeiras) * test: cover mirror hardening edge cases (openclaw#11709) (thanks @gumadeiras)
…law#11709) * fix(doctor): suppress repeated state migration warning * fix: harden state-dir mirror detection + warnings (openclaw#11709) (thanks @gumadeiras) * test: cover mirror hardening edge cases (openclaw#11709) (thanks @gumadeiras)
…law#11709) * fix(doctor): suppress repeated state migration warning * fix: harden state-dir mirror detection + warnings (openclaw#11709) (thanks @gumadeiras) * test: cover mirror hardening edge cases (openclaw#11709) (thanks @gumadeiras)
Summary
State dir migration skipped: target already existswarnings when the legacy state directory is already a symlink mirror of the new~/.openclawtreeTesting
pnpm test src/commands/doctor-state-migrations.test.tspnpm checkNotes
openclaw updateandopenclaw doctorafter successful one-time migrationGreptile Overview
Greptile Summary
This PR adds logic to detect when a legacy state directory is already a symlink “mirror” of the new
~/.openclawtree and, in that case, suppresses the repeatedState dir migration skipped: target already existswarning. It also extends the doctor migration tests to cover mirrored layouts (including nested mirrors) and to keep warnings for real conflicts such as non-symlink entries or symlinks that escape the target tree.The changes are localized to the state-dir auto-migration path in
src/infra/state-migrations.tsand its unit tests insrc/commands/doctor-state-migrations.test.ts.Confidence Score: 3/5
isLegacyTreeSymlinkMirror()returning true on an empty directory will definitely silence thetarget already existswarning for a non-mirrored legacy dir, which is a regression in the doctor output and could hide a manual migration requirement.