Discussion: https://github.com/openclaw/openclaw/discussions/13528
## Checklist
- [x] **Mark as AI-assisted in the PR title or description** - Implemented by 🤖, reviewed by 👨💻
- [x] **Note the degree of testing** - fully tested and I use it myself
- [x] **Include prompts or session logs if possible (super helpful!)** - I can try doing a "resume" on a few sessions, but don't think it'll provide value. Lmk if this is a blocker.
- [x] **Confirm you understand what the code does** - It's simple :)
## Summary of changes
- **ClawDock** - Shell helpers replace verbose `docker-compose` commands with simple `clawdock-*` shortcuts
- **Zero-config setup** - First run auto-detects the OpenClaw project directory from common paths and saves the config for future use
- **No extra dependencies** - Just bash
- **Built-in auth & device pairing helpers** - `clawdock-fix-token`, `clawdock-dashboard`, etc to handle gateay setup, streamline web UI, etc...
- **Updated Docker docs** - Installation docs now include the optional ClawDock helper setup for users who want simplified container management
## Example Usage
```bash
$ clawdock-help
🦞 ClawDock - Docker Helpers for OpenClaw
⚡ Basic Operations
clawdock-start Start the gateway
clawdock-stop Stop the gateway
clawdock-restart Restart the gateway
clawdock-status Check container status
clawdock-logs View live logs (follows)
🐚 Container Access
clawdock-shell Shell into container (openclaw alias ready)
clawdock-cli Run CLI commands (e.g., clawdock-cli status)
clawdock-exec <cmd> Execute command in gateway container
🌐 Web UI & Devices
clawdock-dashboard Open web UI in browser (auto-guides you)
clawdock-devices List device pairings (auto-guides you)
clawdock-approve <id> Approve device pairing (with examples)
⚙️ Setup & Configuration
clawdock-fix-token Configure gateway token (run once)
🔧 Maintenance
clawdock-rebuild Rebuild Docker image
clawdock-clean ⚠️ Remove containers & volumes (nuclear)
🛠️ Utilities
clawdock-health Run health check
clawdock-token Show gateway auth token
clawdock-cd Jump to openclaw project directory
clawdock-config Open config directory (~/.openclaw)
clawdock-workspace Open workspace directory
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🚀 First Time Setup
1. clawdock-start # Start the gateway
2. clawdock-fix-token # Configure token
3. clawdock-dashboard # Open web UI
4. clawdock-devices # If pairing needed
5. clawdock-approve <id> # Approve pairing
💬 WhatsApp Setup
clawdock-shell
> openclaw channels login --channel whatsapp
> openclaw status
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
💡 All commands guide you through next steps!
📚 Docs: https://docs.openclaw.ai
```\n\nCo-authored-by: Gustavo Madeira Santana <gumadeiras@gmail.com>
- Add [Historical context: ...] marker pattern to stripDowngradedToolCallText
- Apply stripDowngradedToolCallText in emitBlockChunk streaming path
- Previously only stripBlockTags ran during streaming, leaking [Tool Call: ...] markers to users
- Add 7 test cases for the new pattern stripping
* docs: clarify which workspace files are injected into context window (#12909)
The system prompt docs listed bootstrap files but omitted MEMORY.md,
which IS injected when present. This led users to assume memory files
are on-demand only and not consuming context tokens.
Changes:
- Add MEMORY.md to the bootstrap file list
- Note that all listed files consume tokens on every turn
- Clarify that memory/*.md daily files are NOT injected (on-demand only)
- Document sub-agent bootstrap filtering (AGENTS.md + TOOLS.md only)
Closes#12909
* docs: mention memory.md alternate filename in bootstrap list
Address review feedback: the runtime also injects lowercase memory.md
(DEFAULT_MEMORY_ALT_FILENAME) when present.
* docs: align memory bootstrap docs (#12937) (thanks @omair445)
---------
Co-authored-by: Luna AI <luna@coredirection.ai>
Co-authored-by: Sebastian <19554889+sebslight@users.noreply.github.com>
* Scripts: add sync-credits.py to populate maintainers/contributors from git/GitHub
* fix(credits): deduplicate contributors by GitHub username and display name
Extends stale automation timelines:
- Issues: 30 days stale → 14 days close (44 total, was 12)
- PRs: 14 days stale → 7 days close (21 total, was 8)
PR #13209
* fix(signal): enforce mention gating for group messages
Signal group messages bypassed mention gating, causing the bot to reply
even when requireMention was enabled and the message did not mention
the bot. This aligns Signal with Slack, Discord, Telegram, and iMessage
which all enforce mention gating correctly.
Fixes#13106
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(signal): keep pending history context for mention-gated skips (#13124) (thanks @zerone0x)
---------
Co-authored-by: Yansu <no-reply@yansu.ai>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>
* fix(ui): prioritize displayName over label in webchat session picker
The session picker dropdown in the webchat UI was showing raw session
keys instead of human-readable display names. resolveSessionDisplayName()
checked label before displayName and formatted displayName-based entries
as key (displayName) instead of displayName (key).
Swap the priority so displayName is checked first, and use a consistent
humanName (key) format for both displayName and label fallbacks.
Fixes#6645
* test: use deterministic updatedAt in session display name tests
* fix: prune stale session entries, cap entry count, and rotate sessions.json
The sessions.json file grows unbounded over time. Every heartbeat tick (default: 30m)
triggers multiple full rewrites, and session keys from groups, threads, and DMs
accumulate indefinitely with large embedded objects (skillsSnapshot,
systemPromptReport). At >50MB the synchronous JSON parse blocks the event loop,
causing Telegram webhook timeouts and effectively taking the bot down.
Three mitigations, all running inside saveSessionStoreUnlocked() on every write:
1. Prune stale entries: remove entries with updatedAt older than 30 days
(configurable via session.maintenance.pruneDays in openclaw.json)
2. Cap entry count: keep only the 500 most recently updated entries
(configurable via session.maintenance.maxEntries). Entries without updatedAt
are evicted first.
3. File rotation: if the existing sessions.json exceeds 10MB before a write,
rename it to sessions.json.bak.{timestamp} and keep only the 3 most recent
backups (configurable via session.maintenance.rotateBytes).
All three thresholds are configurable under session.maintenance in openclaw.json
with Zod validation. No env vars.
Existing tests updated to use Date.now() instead of epoch-relative timestamps
(1, 2, 3) that would be incorrectly pruned as stale.
27 new tests covering pruning, capping, rotation, and integration scenarios.
* feat: auto-prune expired cron run sessions (#12289)
Add TTL-based reaper for isolated cron run sessions that accumulate
indefinitely in sessions.json.
New config option:
cron.sessionRetention: string | false (default: '24h')
The reaper runs piggy-backed on the cron timer tick, self-throttled
to sweep at most every 5 minutes. It removes session entries matching
the pattern cron:<jobId>:run:<uuid> whose updatedAt + retention < now.
Design follows the Kubernetes ttlSecondsAfterFinished pattern:
- Sessions are persisted normally (observability/debugging)
- A periodic reaper prunes expired entries
- Configurable retention with sensible default
- Set to false to disable pruning entirely
Files changed:
- src/config/types.cron.ts: Add sessionRetention to CronConfig
- src/config/zod-schema.ts: Add Zod validation for sessionRetention
- src/cron/session-reaper.ts: New reaper module (sweepCronRunSessions)
- src/cron/session-reaper.test.ts: 12 tests covering all paths
- src/cron/service/state.ts: Add cronConfig/sessionStorePath to deps
- src/cron/service/timer.ts: Wire reaper into onTimer tick
- src/gateway/server-cron.ts: Pass config and session store path to deps
Closes#12289
* fix: sweep cron session stores per agent
* docs: add changelog for session maintenance (#13083) (thanks @skyfallsin, @Glucksberg)
* fix: add warn-only session maintenance mode
* fix: warn-only maintenance defaults to active session
* fix: deliver maintenance warnings to active session
* docs: add session maintenance examples
* fix: accept duration and size maintenance thresholds
* refactor: share cron run session key check
* fix: format issues and replace defaultRuntime.warn with console.warn
---------
Co-authored-by: Pradeep Elankumaran <pradeepe@gmail.com>
Co-authored-by: Glucksberg <markuscontasul@gmail.com>
Co-authored-by: max <40643627+quotentiroler@users.noreply.github.com>
Co-authored-by: quotentiroler <max.nussbaumer@maxhealth.tech>
* fix(tools): correct Grok response parsing for xAI Responses API
The xAI Responses API returns content in output[0].content[0].text,
not in output_text field. Updated GrokSearchResponse type and
runGrokSearch to extract content from the correct path.
Fixes the 'No response' issue when using Grok web search.
* fix(tools): harden Grok web_search parsing (#13049) (thanks @ereid7)
---------
Co-authored-by: erai <erai@erais-Mac-mini.local>
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>