@cleocode/cleo 2026.6.9 → 2026.6.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/cleo.js CHANGED
@@ -7,6 +7,14 @@
7
7
  * resolution (before any JS code executes), so it must be suppressed at the
8
8
  * Node runtime level, not in application code.
9
9
  *
10
+ * T11829 (fleet OOM fail-safe): the wrapper also caps the V8 old-space heap
11
+ * (`--max-old-space-size`) so a single runaway `cleo` invocation throws a
12
+ * recoverable, single-process JavaScript heap OOM instead of growing unbounded
13
+ * and contributing to a host-wide SIGKILL. The cap is overridable via
14
+ * `CLEO_MAX_OLD_SPACE_MB` for the rare command (large export/import) that needs
15
+ * more headroom. This is a process-level guard ABOVE the per-connection SQLite
16
+ * memory bounding in dual-scope-db.ts — defense in depth.
17
+ *
10
18
  * See: https://github.com/kryptobaseddev/cleo/issues/XXX (T1138)
11
19
  */
12
20
 
@@ -19,11 +27,25 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
19
27
  const cliPath = resolve(__dirname, '../dist/cli/index.js');
20
28
  const args = process.argv.slice(2);
21
29
 
30
+ // T11829: cap V8 old-space so a runaway throws a recoverable single-process OOM
31
+ // rather than a host SIGKILL. Default 1536 MB; override via CLEO_MAX_OLD_SPACE_MB.
32
+ const maxOldSpaceMb = Number.parseInt(process.env.CLEO_MAX_OLD_SPACE_MB ?? '', 10);
33
+ const heapCapMb = Number.isFinite(maxOldSpaceMb) && maxOldSpaceMb > 0 ? maxOldSpaceMb : 1536;
34
+
22
35
  try {
23
- execFileSync('node', ['--disable-warning=ExperimentalWarning', cliPath, ...args], {
24
- stdio: 'inherit',
25
- cwd: process.cwd(),
26
- });
36
+ execFileSync(
37
+ 'node',
38
+ [
39
+ `--max-old-space-size=${heapCapMb}`,
40
+ '--disable-warning=ExperimentalWarning',
41
+ cliPath,
42
+ ...args,
43
+ ],
44
+ {
45
+ stdio: 'inherit',
46
+ cwd: process.cwd(),
47
+ },
48
+ );
27
49
  } catch (error) {
28
50
  process.exit(error.status || 1);
29
51
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cleocode/cleo",
3
- "version": "2026.6.9",
3
+ "version": "2026.6.11",
4
4
  "description": "CLEO CLI — the assembled product consuming @cleocode/core",
5
5
  "type": "module",
6
6
  "main": "./dist/cli/index.js",
@@ -30,17 +30,17 @@
30
30
  "tree-sitter-rust": "0.23.1",
31
31
  "tree-sitter-typescript": "^0.23.2",
32
32
  "yaml": "^2.8.3",
33
- "@cleocode/animations": "2026.6.9",
34
- "@cleocode/cant": "2026.6.9",
35
- "@cleocode/contracts": "2026.6.9",
36
- "@cleocode/caamp": "2026.6.9",
37
- "@cleocode/core": "2026.6.9",
38
- "@cleocode/lafs": "2026.6.9",
39
- "@cleocode/paths": "2026.6.9",
40
- "@cleocode/nexus": "2026.6.9",
41
- "@cleocode/playbooks": "2026.6.9",
42
- "@cleocode/runtime": "2026.6.9",
43
- "@cleocode/worktree": "2026.6.9"
33
+ "@cleocode/animations": "2026.6.11",
34
+ "@cleocode/caamp": "2026.6.11",
35
+ "@cleocode/cant": "2026.6.11",
36
+ "@cleocode/contracts": "2026.6.11",
37
+ "@cleocode/core": "2026.6.11",
38
+ "@cleocode/nexus": "2026.6.11",
39
+ "@cleocode/paths": "2026.6.11",
40
+ "@cleocode/lafs": "2026.6.11",
41
+ "@cleocode/playbooks": "2026.6.11",
42
+ "@cleocode/runtime": "2026.6.11",
43
+ "@cleocode/worktree": "2026.6.11"
44
44
  },
45
45
  "engines": {
46
46
  "node": ">=24.16.0"
@@ -368,16 +368,29 @@ function buildSystemdUnit(cleoExec, scope) {
368
368
  ? `CLEO Sentient Daemon (epic ${scope.scopeEpicId} scoped)`
369
369
  : 'CLEO Sentient Daemon (autonomous task hygiene + dream cycles)';
370
370
 
371
+ // T11829 (fleet OOM fail-safe): bound the daemon's blast radius.
372
+ // - StartLimitIntervalSec/StartLimitBurst: cap a crash-loop. The prior unit
373
+ // respawned every RestartSec=5 with NO ceiling, so — combined with the
374
+ // never-converging migration journal — it stacked opens until the host
375
+ // OOM-killed. systemd now stops restarting after 5 failures in 60 s.
376
+ // - NODE_OPTIONS=--max-old-space-size: a runaway daemon tick throws a
377
+ // recoverable single-process JS heap OOM instead of growing unbounded.
378
+ // - MemoryMax: best-effort soft cgroup ceiling (enforced only when the user
379
+ // manager has memory-cgroup delegation; harmless otherwise).
371
380
  return `[Unit]
372
381
  Description=${description}
373
382
  Documentation=https://github.com/kryptobaseddev/cleocode
374
383
  After=network.target
384
+ StartLimitIntervalSec=60
385
+ StartLimitBurst=5
375
386
 
376
387
  [Service]
377
388
  Type=simple
378
389
  ExecStart=${cleoExec} daemon start --foreground
379
390
  Restart=on-failure
380
391
  RestartSec=5
392
+ MemoryMax=2G
393
+ Environment=NODE_OPTIONS=--max-old-space-size=1536
381
394
  StandardOutput=append:${logFile}
382
395
  StandardError=append:${logFile}
383
396
  Environment=CLEO_SENTIENT_DAEMON=1${scopeEnv}