* feat: Implement Telegram video note support with tests and docs
* fixing lint
* feat: add doctor-state-integrity command, Telegram messaging, and PowerShell Docker setup scripts.
* Update src/telegram/send.video-note.test.ts
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
* fix: Set video note follow-up text to undefined for empty input and adjust caption test expectation.
* test: add assertion for `sendMessage` with reply markup and HTML parse mode in `send.video-note` test.
* docs: add changelog entry for Telegram video notes
---------
Co-authored-by: Evgenii Utkin <thewulf7@gmail.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: CLAWDINATOR Bot <clawdinator[bot]@users.noreply.github.com>
* fix(skills): ignore Python venvs and caches in skills watcher
Add .venv, venv, __pycache__, .mypy_cache, .pytest_cache, build, and
.cache to the default ignored patterns for the skills watcher.
This prevents file descriptor exhaustion when a skill contains a Python
virtual environment with tens of thousands of files, which was causing
EBADF spawn errors on macOS.
Fixes#1056
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs: add changelog entry for skills watcher ignores
* docs: fill changelog PR number
---------
Co-authored-by: Kyle Howells <freerunnering@gmail.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: CLAWDINATOR Bot <clawdinator[bot]@users.noreply.github.com>
* Gateway: preserve Pi transcript parentId for injected messages
Thread: unknown
When: 2026-02-08 20:08 CST
Repo: https://github.com/openclaw/openclaw.git
Branch: codex/wip/2026-02-09/compact-post-compaction-parentid-fix
Problem
- Post-compaction turns sometimes lost the compaction summary + kept suffix in the *next* provider request.
- Root cause was session graph corruption: gateway appended "stopReason: injected" transcript lines via raw JSONL writes without `parentId`.
- Pi's `SessionManager.buildSessionContext()` walks the `parentId` chain from the current leaf; missing `parentId` can sever the active branch and hide the compaction entry.
Fix
- Use `SessionManager.appendMessage(...)` for injected assistant transcript writes so `parentId` is set to the current leaf.
- Route `chat.inject` through the same helper to avoid duplicating the broken raw JSONL append logic.
Why This Matters
- The compaction algorithm may be correct, but if the leaf chain is broken right after compaction, the provider payload cannot include the summary/suffix "shape" Pi expects.
Testing
- pnpm test src/agents/pi-embedded-helpers.post-compaction-shape.test.ts src/agents/pi-embedded-runner/run.overflow-compaction.post-context.test.ts
- pnpm build
Notes
- This is provider-shape agnostic: it fixes transcript structure so Anthropic/Gemini/etc all see the same post-compaction context.
Resume
- If post-compaction looks wrong again, inspect the session transcript for entries missing `parentId` immediately after `type: compaction`.
* Gateway: guardrail test for transcript parentId (chat.inject)
* Gateway: guardrail against raw transcript appends (chat.ts)
* Gateway: add local AGENTS.md note to preserve Pi transcript parentId chain
* Changelog: note gateway post-compaction amnesia fix
* Gateway: store injected transcript messages with valid stopReason
* Gateway: use valid stopReason in injected fallback
* fix: compile bundled hook handlers in tsdown build
The migration from tsc to tsdown in 2026.2.2 dropped bundled hook handlers
from the build output. The copy-hook-metadata.ts script only copies HOOK.md
metadata files, not the handler.ts source files. Without corresponding tsdown
entry points, the handlers were never compiled to JS, causing
`openclaw hooks list` to show 0 hooks on npm installs.
This adds each bundled hook handler and the llm-slug-generator (dynamically
imported by session-memory) as tsdown entry points:
- src/hooks/bundled/session-memory/handler.ts
- src/hooks/bundled/command-logger/handler.ts
- src/hooks/bundled/boot-md/handler.ts
- src/hooks/bundled/soul-evil/handler.ts
- src/hooks/llm-slug-generator.ts
Regression introduced in 2026.2.2; versions 2026.1.29–2026.2.1 worked
correctly under the previous tsc build.
* refactor: use glob for bundled hook entries, fix dist output paths
- Replace hardcoded entry list with glob pattern in tsdown.config.ts
so new hooks are auto-discovered (matching scripts/copy-hook-metadata.ts)
- Remove inconsistent comment block from tsdown.config.ts
- Fix copy-hook-metadata.ts to copy HOOK.md to dist/bundled/ (matching
the runtime resolution in bundled-dir.ts which resolves path.join(moduleDir, 'bundled')
relative to the chunk in dist/)
- Update stale path comment in session-memory handler
* macOS: honor Nix defaults suite; auto launch in Nix mode
Fixes repeated onboarding in Nix deployments by detecting nixMode from the stable defaults suite (ai.openclaw.mac) and bridging key settings into the current defaults domain.
Also enables LaunchAgent autostart by default in Nix mode (escape hatch: openclaw.nixAutoLaunchAtLogin=false).
* macOS: keep Nix mode fix focused
Drop the automatic launch-at-login behavior from the Nix defaults patch; keep this PR scoped to reliable nixMode detection + defaults bridging.
* macOS: simplify nixMode fix
Remove the defaults-bridging helper and rely on a single, stable defaults suite (ai.openclaw.mac) for nixMode detection when running as an app bundle. This keeps the fix focused on onboarding suppression and rename churn resilience.
* macOS: fix nixMode defaults suite churn (#12205)
* test: normalize paths in OPENCLAW_HOME tests for cross-platform support
* test: normalize paths in Nix integration tests for cross-platform support
* test: remove unnecessary Windows skip from pi-embedded-runner test
* test: fix nix integration tests for path.resolve behavior
* fix(paths): structurally resolve home dir to prevent Windows path bugs
Extract resolveRawHomeDir as a private function and gate the public
resolveEffectiveHomeDir through a single path.resolve() exit point.
This makes it structurally impossible for unresolved paths (missing
drive letter on Windows) to escape the function, regardless of how
many return paths exist in the raw lookup logic.
Simplify resolveRequiredHomeDir to only resolve the process.cwd()
fallback, since resolveEffectiveHomeDir now returns resolved values.
Fix shortenMeta in tool-meta.ts: the colon-based split for file:line
patterns (e.g. file.txt:12) conflicts with Windows drive letters
(C:\...) because indexOf(":") matches the drive colon first.
shortenHomeInString already handles file:line patterns correctly via
split/join, so the colon split was both unnecessary and harmful.
Update test assertions across all affected files to use path.resolve()
in expected values and input strings so they match the now-correct
resolved output on both Unix and Windows.
Fixes#12119
* fix(changelog): add paths Windows fix entry (#12125)
---------
Co-authored-by: Sebastian <19554889+sebslight@users.noreply.github.com>
* fix: use .js extension for ESM imports of RoutePeerKind
The imports incorrectly used .ts extension which doesn't resolve
with moduleResolution: NodeNext. Changed to .js and added 'type'
import modifier.
* fix tsconfig
* refactor: unify peer kind to ChatType, rename dm to direct
- Replace RoutePeerKind with ChatType throughout codebase
- Change 'dm' literal values to 'direct' in routing/session keys
- Keep backward compat: normalizeChatType accepts 'dm' -> 'direct'
- Add ChatType export to plugin-sdk, deprecate RoutePeerKind
- Update session key parsing to accept both 'dm' and 'direct' markers
- Update all channel monitors and extensions to use ChatType
BREAKING CHANGE: Session keys now use 'direct' instead of 'dm'.
Existing 'dm' keys still work via backward compat layer.
* fix tests
* test: update session key expectations for dmdirect migration
- Fix test expectations to expect :direct: in generated output
- Add explicit backward compat test for normalizeChatType('dm')
- Keep input test data with :dm: keys to verify backward compat
* fix: accept legacy 'dm' in session key parsing for backward compat
getDmHistoryLimitFromSessionKey now accepts both :dm: and :direct:
to ensure old session keys continue to work correctly.
* test: add explicit backward compat tests for dmdirect migration
- session-key.test.ts: verify both :dm: and :direct: keys are valid
- getDmHistoryLimitFromSessionKey: verify both formats work
* feat: backward compat for resetByType.dm config key
* test: skip unix-path Nix tests on Windows
Closes#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.
* Add GitHub Copilot models to xhigh list
* fix(thinking): add xhigh copilot tests and changelog (#11646) (thanks @seans-openclawbot)
---------
Co-authored-by: Sean Dai <sdai@gatech.edu>
Co-authored-by: Sebastian <19554889+sebslight@users.noreply.github.com>
* 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 (#11543) (thanks @ezhikkk)
---------
Co-authored-by: Параша <parasha@openclaw.local>
Co-authored-by: Muhammed Mukhthar CM <mukhtharcm@gmail.com>
* 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 (#11551) (thanks @tyler6204)
* 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 (#11641) (thanks @tyler6204)
* 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 (#4824) (thanks @kossoy)
* fix: align state-dir fallbacks in hooks and agent paths (#4824) (thanks @kossoy)
---------
Co-authored-by: Gustavo Madeira Santana <gumadeiras@gmail.com>