flavor-code 1.4.0-beta.4 → 1.4.0-beta.5

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.
@@ -4,7 +4,7 @@ import {
4
4
  message,
5
5
  redactErrorText,
6
6
  redactSecrets
7
- } from "./chunk-DCNUBQCH.js";
7
+ } from "./chunk-J7TLT6LR.js";
8
8
 
9
9
  // src/rpc/server.ts
10
10
  import { createInterface } from "readline";
@@ -8,7 +8,7 @@ var MEMORY_RESTART_MARKER_FILE = "memory-restart.json";
8
8
  var MEMORY_RESTART_MAX_ATTEMPTS = 24;
9
9
  var MEMORY_RESTART_WINDOW_MS = 60 * 60 * 1e3;
10
10
  var MEMORY_RESTART_MIN_GAP_MS = 5 * 60 * 1e3;
11
- var MEMORY_RESTART_CONTINUATION_TTL_MS = 10 * 60 * 1e3;
11
+ var MEMORY_RESTART_CONTINUATION_TTL_MS = 24 * 60 * 60 * 1e3;
12
12
  var SESSION_ID_PATTERN = /^session-[A-Za-z0-9_-]+$/u;
13
13
  var rotationActive = false;
14
14
  function markMemoryRotation() {
package/dist/cli-main.js CHANGED
@@ -3,7 +3,7 @@ import { createRequire } from "node:module"; const require = createRequire(impor
3
3
  import {
4
4
  FlavorRpcServer,
5
5
  TraceRecorder
6
- } from "./chunk-4RR5VVX4.js";
6
+ } from "./chunk-JZVC4477.js";
7
7
  import {
8
8
  staticTaskLines
9
9
  } from "./chunk-2BF7CVWZ.js";
@@ -29,10 +29,10 @@ import {
29
29
  redactErrorText,
30
30
  runDoctor,
31
31
  runPalBroker
32
- } from "./chunk-DCNUBQCH.js";
32
+ } from "./chunk-J7TLT6LR.js";
33
33
  import {
34
34
  MEMORY_RESTART_EXIT_CODE
35
- } from "./chunk-LKQTBL3R.js";
35
+ } from "./chunk-N5MXHJKD.js";
36
36
  import {
37
37
  McpServerConfigSchema,
38
38
  McpServerNameSchema,
@@ -900,7 +900,7 @@ async function runInteractiveCli(props) {
900
900
  const [{ render, AlternateScreen }, { createElement }, { App }] = await Promise.all([
901
901
  import("./claude-ink-ECZ6QF3P.js"),
902
902
  import("react"),
903
- import("./app-UWIEIWBQ.js")
903
+ import("./app-SXNJDSI2.js")
904
904
  ]);
905
905
  const instance = await render(createElement(
906
906
  AlternateScreen,
package/dist/cli.js CHANGED
@@ -5,22 +5,24 @@ import {
5
5
  memoryRestartArgs,
6
6
  memoryRestartMarkerPath,
7
7
  parseMemoryRestartMarker
8
- } from "./chunk-LKQTBL3R.js";
8
+ } from "./chunk-N5MXHJKD.js";
9
9
  import "./chunk-S32JRDZK.js";
10
10
 
11
11
  // src/launcher.ts
12
12
  import { spawn } from "child_process";
13
- import { realpathSync, readFileSync } from "fs";
13
+ import { mkdirSync, realpathSync, readFileSync, rmSync } from "fs";
14
14
  import { totalmem } from "os";
15
+ import { join } from "path";
15
16
  import { fileURLToPath } from "url";
16
17
  function needsRelaunch(runtime) {
17
18
  if (!runtime.execArgv.some((argument) => argument === "--report-on-fatalerror")) return true;
18
19
  if (!runtime.execArgv.some((argument) => argument.startsWith("--heapsnapshot-near-heap-limit"))) return true;
20
+ if (!runtime.execArgv.some((argument) => argument === "--heap-prof")) return true;
19
21
  return !runtime.execArgv.some((argument) => argument === "--expose-gc");
20
22
  }
21
23
  var HEAP_HEADROOM_MB = 8192;
22
24
  var HEAP_HEADROOM_MIN_TOTALMEM = 12 * 1024 * 1024 * 1024;
23
- function cliMainArguments(mainPath, argv) {
25
+ function cliMainArguments(mainPath, argv, heapProfile) {
24
26
  const flags = [
25
27
  // Fatal V8 errors (heap OOM, native crashes) bypass crash-guard.ts and
26
28
  // leave only an unusable native stack. Ask Node to dump a diagnostic
@@ -31,11 +33,20 @@ function cliMainArguments(mainPath, argv) {
31
33
  // Capture one heap snapshot as the heap nears its limit so the next
32
34
  // crash leaves a .heapsnapshot retainer trail next to the report.
33
35
  "--heapsnapshot-near-heap-limit=1",
36
+ // A full snapshot is intentionally reserved for a hard OOM. Sparse
37
+ // allocation sampling has much lower overhead and still records the
38
+ // allocating call stacks responsible for a controlled watermark
39
+ // restart, where --heapsnapshot-near-heap-limit never fires.
40
+ "--heap-prof",
41
+ "--heap-prof-interval=1048576",
34
42
  // The heap watermarks are GC-verified: heapUsed counts uncollected
35
43
  // garbage, and stopping turns or rotating on garbage alone would waste
36
44
  // work. Exposing gc lets the watermark measure the live set instead.
37
45
  "--expose-gc"
38
46
  ];
47
+ if (heapProfile !== void 0) {
48
+ flags.push(`--heap-prof-dir=${heapProfile.directory}`, `--heap-prof-name=${heapProfile.name}`);
49
+ }
39
50
  const processHeapFlag = process.execArgv.find((argument) => argument.startsWith("--max-old-space-size"));
40
51
  const argvHeapFlag = argv.find((argument) => argument.startsWith("--max-old-space-size"));
41
52
  const userHeapFlag = processHeapFlag ?? argvHeapFlag;
@@ -62,8 +73,19 @@ async function launchCli() {
62
73
  }
63
74
  const mainPath = fileURLToPath(mainUrl);
64
75
  let argv = process.argv.slice(2);
76
+ let childSequence = 0;
65
77
  for (; ; ) {
66
- const code = await spawnAndWait(mainPath, argv);
78
+ const profileDirectory = join(process.cwd(), ".flavor", "tmp");
79
+ mkdirSync(profileDirectory, { recursive: true });
80
+ const profileName = `heap-profile-${Date.now()}-${process.pid}-${childSequence++}.heapprofile`;
81
+ const profilePath = join(profileDirectory, profileName);
82
+ const code = await spawnAndWait(mainPath, argv, { directory: profileDirectory, name: profileName });
83
+ if (code === 0) {
84
+ rmSync(profilePath, { force: true });
85
+ } else {
86
+ process.stderr.write(`flavor launcher: retained allocation profile ${profilePath}
87
+ `);
88
+ }
67
89
  if (code === MEMORY_RESTART_EXIT_CODE) {
68
90
  let marker;
69
91
  try {
@@ -86,8 +108,8 @@ async function launchCli() {
86
108
  return;
87
109
  }
88
110
  }
89
- async function spawnAndWait(mainPath, argv) {
90
- const child = spawn(process.execPath, cliMainArguments(mainPath, argv), { stdio: "inherit" });
111
+ async function spawnAndWait(mainPath, argv, heapProfile) {
112
+ const child = spawn(process.execPath, cliMainArguments(mainPath, argv, heapProfile), { stdio: "inherit" });
91
113
  const ignoreSignal = () => {
92
114
  };
93
115
  process.on("SIGINT", ignoreSignal);