openclaw/src/cli
Gustavo Madeira Santana e19a23520c
fix: unify session maintenance and cron run pruning (#13083)
* 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>
2026-02-09 20:42:35 -08:00
..
browser-cli-actions-input chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
cron-cli Centralize date/time formatting utilities (#11831) 2026-02-08 04:53:31 -08:00
daemon-cli fix(gateway): use LAN IP for WebSocket/probe URLs when bind=lan (#11448) 2026-02-07 19:16:51 -06:00
gateway-cli chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
node-cli chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
nodes-cli Centralize date/time formatting utilities (#11831) 2026-02-08 04:53:31 -08:00
program feat: adding support for Together ai provider (#10304) 2026-02-10 08:49:34 +09:00
acp-cli.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
argv.test.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
argv.ts chore: Enable "curly" rule to avoid single-statement if confusion/errors. 2026-01-31 16:19:20 +09:00
banner.ts chore: Enable "curly" rule to avoid single-statement if confusion/errors. 2026-01-31 16:19:20 +09:00
browser-cli-actions-input.ts refactor(src): split oversized modules 2026-01-14 01:17:56 +00:00
browser-cli-actions-observe.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
browser-cli-debug.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
browser-cli-examples.ts refactor: rename to openclaw 2026-01-30 03:16:21 +01:00
browser-cli-extension.test.ts fix: resolve bundled chrome extension assets (#8914) (thanks @kelvinCB) 2026-02-05 00:17:09 -08:00
browser-cli-extension.ts fix: resolve bundled chrome extension assets (#8914) (thanks @kelvinCB) 2026-02-05 00:17:09 -08:00
browser-cli-inspect.test.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
browser-cli-inspect.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
browser-cli-manage.ts refactor: rename to openclaw 2026-01-30 03:16:21 +01:00
browser-cli-shared.ts chore: Enable "curly" rule to avoid single-statement if confusion/errors. 2026-01-31 16:19:20 +09:00
browser-cli-state.cookies-storage.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
browser-cli-state.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
browser-cli.test.ts revert: Switch back to `tsc` for compiling. 2026-01-31 18:31:49 +09:00
browser-cli.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
channel-auth.ts chore: migrate to oxlint and oxfmt 2026-01-14 15:02:19 +00:00
channel-options.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
channels-cli.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
cli-name.ts chore: Enable "curly" rule to avoid single-statement if confusion/errors. 2026-01-31 16:19:20 +09:00
cli-utils.ts refactor: consolidate duplicate utility functions (#12439) 2026-02-08 23:59:43 -08:00
command-format.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
command-options.ts chore: migrate to oxlint and oxfmt 2026-01-14 15:02:19 +00:00
completion-cli.ts Deduplicate more 2026-02-09 18:56:58 -08:00
config-cli.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
cron-cli.test.ts feat(cron): enhance delivery modes and job configuration 2026-02-04 01:03:59 -08:00
cron-cli.ts refactor(src): split oversized modules 2026-01-14 01:17:56 +00:00
daemon-cli.coverage.test.ts chore: Enable "curly" rule to avoid single-statement if confusion/errors. 2026-01-31 16:19:20 +09:00
daemon-cli.ts refactor(src): split oversized modules 2026-01-14 01:17:56 +00:00
deps.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
devices-cli.ts Centralize date/time formatting utilities (#11831) 2026-02-08 04:53:31 -08:00
directory-cli.ts chore: Enable `no-unnecessary-template-expression` lint rule. 2026-02-02 15:37:05 +09:00
dns-cli.test.ts refactor: rename to openclaw 2026-01-30 03:16:21 +01:00
dns-cli.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
docs-cli.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
exec-approvals-cli.test.ts fix: add diagnostics cache trace config (#1370) (thanks @parubets) 2026-01-21 10:23:30 +00:00
exec-approvals-cli.ts Centralize date/time formatting utilities (#11831) 2026-02-08 04:53:31 -08:00
gateway-cli.coverage.test.ts fix(exec-approvals): coerce bare string allowlist entries (#9903) (thanks @mcaxtr) 2026-02-05 15:52:51 -08:00
gateway-cli.ts refactor(src): split oversized modules 2026-01-14 01:17:56 +00:00
gateway-rpc.ts fix(cron): fix timeout, add timestamp validation, enable file sync 2026-02-04 01:03:59 -08:00
gateway.sigterm.test.ts chore: Enable "curly" rule to avoid single-statement if confusion/errors. 2026-01-31 16:19:20 +09:00
help-format.ts chore: Enable "curly" rule to avoid single-statement if confusion/errors. 2026-01-31 16:19:20 +09:00
hooks-cli.test.ts refactor: rename to openclaw 2026-01-30 03:16:21 +01:00
hooks-cli.ts fix: harden plugin and hook install paths 2026-02-02 02:07:47 -08:00
logs-cli.test.ts refactor: rename to openclaw 2026-01-30 03:16:21 +01:00
logs-cli.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
memory-cli.test.ts fix(memory/qmd): throttle embed + citations auto + restore --force 2026-02-02 23:45:05 -08:00
memory-cli.ts chore: apply formatter 2026-02-02 23:45:05 -08:00
models-cli.test.ts chore: Enable more lint rules, disable some that trigger a lot. Will clean up later. 2026-01-31 16:04:04 +09:00
models-cli.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
node-cli.ts fix: resolve ci failures 2026-01-18 08:45:29 +00:00
nodes-camera.test.ts refactor: rename to openclaw 2026-01-30 03:16:21 +01:00
nodes-camera.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
nodes-canvas.test.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
nodes-canvas.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
nodes-cli.coverage.test.ts Revert "iOS: wire node services and tests" 2026-02-02 17:36:49 +00:00
nodes-cli.ts refactor(src): split oversized modules 2026-01-14 01:17:56 +00:00
nodes-run.ts chore: Enable "curly" rule to avoid single-statement if confusion/errors. 2026-01-31 16:19:20 +09:00
nodes-screen.test.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
nodes-screen.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
outbound-send-deps.ts style: oxfmt format 2026-01-17 05:48:56 +00:00
pairing-cli.test.ts chore: Enable "curly" rule to avoid single-statement if confusion/errors. 2026-01-31 16:19:20 +09:00
pairing-cli.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
parse-bytes.test.ts fix: unify session maintenance and cron run pruning (#13083) 2026-02-09 20:42:35 -08:00
parse-bytes.ts fix: unify session maintenance and cron run pruning (#13083) 2026-02-09 20:42:35 -08:00
parse-duration.test.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
parse-duration.ts chore: Enable "curly" rule to avoid single-statement if confusion/errors. 2026-01-31 16:19:20 +09:00
parse-timeout.ts chore: Enable "curly" rule to avoid single-statement if confusion/errors. 2026-01-31 16:19:20 +09:00
plugin-registry.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
plugins-cli.ts fix(cli): improve plugins list source display 2026-02-09 13:05:48 -06:00
ports.ts chore: We have a sleep at home. The sleep at home: 2026-02-02 21:44:02 +09:00
profile-utils.ts chore: Enable "curly" rule to avoid single-statement if confusion/errors. 2026-01-31 16:19:20 +09:00
profile.test.ts fix(paths): structurally resolve home dir to prevent Windows path bugs (#12125) 2026-02-08 20:06:29 -05:00
profile.ts fix(paths): respect OPENCLAW_HOME for all internal path resolution (#12091) 2026-02-08 16:20:13 -05:00
program.force.test.ts chore: Enable "curly" rule to avoid single-statement if confusion/errors. 2026-01-31 16:19:20 +09:00
program.nodes-basic.test.ts feat: filter nodes list/status 2026-01-21 04:39:15 +00:00
program.nodes-media.test.ts chore: Enable more lint rules, disable some that trigger a lot. Will clean up later. 2026-01-31 16:04:04 +09:00
program.smoke.test.ts feat: adding support for Together ai provider (#10304) 2026-02-10 08:49:34 +09:00
program.ts refactor(src): split oversized modules 2026-01-14 01:17:56 +00:00
progress.test.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
progress.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
prompt.test.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
prompt.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
route.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
run-main.test.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
run-main.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
sandbox-cli.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
security-cli.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
skills-cli.test.ts fix(ui): fix web UI after tsdown migration and typing changes 2026-02-03 13:56:20 -05:00
skills-cli.ts fix(ui): fix web UI after tsdown migration and typing changes 2026-02-03 13:56:20 -05:00
system-cli.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
tagline.ts chore: Enable "curly" rule to avoid single-statement if confusion/errors. 2026-01-31 16:19:20 +09:00
tui-cli.ts refactor: rename to openclaw 2026-01-30 03:16:21 +01:00
update-cli.test.ts chore: Migrate to tsdown, speed up JS bundling by ~10x (thanks @hyf0). 2026-02-03 20:18:16 +09:00
update-cli.ts Deduplicate more 2026-02-09 18:56:58 -08:00
wait.test.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00
wait.ts chore: format to 2-space and bump changelog 2025-11-26 00:53:53 +01:00
webhooks-cli.ts chore: Enable "experimentalSortImports" in Oxfmt and reformat all imorts. 2026-02-01 10:03:47 +09:00