flavor-code 1.3.15 → 1.3.17

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/dist/cli.js CHANGED
@@ -1,22 +1,32 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from "node:module"; const require = createRequire(import.meta.url);
3
+ import {
4
+ MEMORY_RESTART_EXIT_CODE,
5
+ memoryRestartArgs,
6
+ memoryRestartMarkerPath,
7
+ parseMemoryRestartMarker
8
+ } from "./chunk-CIVPKHF4.js";
3
9
  import "./chunk-S32JRDZK.js";
4
10
 
5
11
  // src/launcher.ts
6
12
  import { spawn } from "child_process";
7
- import { realpathSync } from "fs";
8
- import { release } from "os";
13
+ import { realpathSync, readFileSync } from "fs";
9
14
  import { fileURLToPath } from "url";
10
- function needsWindowsMaglevWorkaround(runtime) {
11
- if (runtime.platform !== "win32") return false;
12
- const build = Number(runtime.osRelease.split(".")[2]);
13
- const major = Number(runtime.nodeVersion.replace(/^v/u, "").split(".")[0]);
14
- if (build !== 26200 || major < 24) return false;
15
- return !runtime.execArgv.some((argument) => argument === "--no-maglev" || argument === "--jitless");
15
+ function needsRelaunch(runtime) {
16
+ if (!runtime.execArgv.some((argument) => argument === "--report-on-fatalerror")) return true;
17
+ return !runtime.execArgv.some((argument) => argument.startsWith("--heapsnapshot-near-heap-limit"));
16
18
  }
17
- function cliMainArguments(runtime, mainPath, argv) {
19
+ function cliMainArguments(mainPath, argv) {
18
20
  return [
19
- ...needsWindowsMaglevWorkaround(runtime) ? ["--no-maglev"] : [],
21
+ // Fatal V8 errors (heap OOM, native crashes) bypass crash-guard.ts and
22
+ // leave only an unusable native stack. Ask Node to dump a diagnostic
23
+ // report next to the working directory so the next crash has a scene.
24
+ "--report-on-fatalerror",
25
+ // The 2026-08-29 OOM reports showed about 4.28GB used at a 4.50GB
26
+ // heap limit while the provider reported roughly 162K context tokens.
27
+ // Capture one heap snapshot as the heap nears its limit so the next
28
+ // crash leaves a .heapsnapshot retainer trail next to the report.
29
+ "--heapsnapshot-near-heap-limit=1",
20
30
  mainPath,
21
31
  ...argv
22
32
  ];
@@ -24,31 +34,50 @@ function cliMainArguments(runtime, mainPath, argv) {
24
34
  async function launchCli() {
25
35
  const mainUrl = new URL("./cli-main.js", import.meta.url);
26
36
  const runtime = {
27
- platform: process.platform,
28
- osRelease: release(),
29
- nodeVersion: process.version,
30
37
  execArgv: process.execArgv
31
38
  };
32
- if (!needsWindowsMaglevWorkaround(runtime)) {
39
+ if (!needsRelaunch(runtime)) {
33
40
  const cli = await import(mainUrl.href);
34
41
  await cli.runCli(process.argv);
35
42
  return;
36
43
  }
37
- const child = spawn(
38
- process.execPath,
39
- cliMainArguments(runtime, fileURLToPath(mainUrl), process.argv.slice(2)),
40
- { stdio: "inherit" }
41
- );
44
+ const mainPath = fileURLToPath(mainUrl);
45
+ let argv = process.argv.slice(2);
46
+ for (; ; ) {
47
+ const code = await spawnAndWait(mainPath, argv);
48
+ if (code === MEMORY_RESTART_EXIT_CODE) {
49
+ let marker;
50
+ try {
51
+ marker = parseMemoryRestartMarker(readFileSync(memoryRestartMarkerPath(process.cwd()), "utf8"));
52
+ } catch {
53
+ marker = void 0;
54
+ }
55
+ const resumed = memoryRestartArgs(argv, marker);
56
+ if (resumed !== void 0) {
57
+ process.stderr.write(`flavor launcher: heap watermark restart, resuming session ${marker.sessionId}
58
+ `);
59
+ argv = resumed;
60
+ continue;
61
+ }
62
+ if (marker !== void 0) {
63
+ process.stderr.write("flavor launcher: heap watermark restart budget exhausted; restart manually and consider a fresh session.\n");
64
+ }
65
+ }
66
+ process.exitCode = code;
67
+ return;
68
+ }
69
+ }
70
+ async function spawnAndWait(mainPath, argv) {
71
+ const child = spawn(process.execPath, cliMainArguments(mainPath, argv), { stdio: "inherit" });
42
72
  const ignoreSignal = () => {
43
73
  };
44
74
  process.on("SIGINT", ignoreSignal);
45
75
  process.on("SIGBREAK", ignoreSignal);
46
76
  try {
47
- const code = await new Promise((resolvePromise, reject) => {
77
+ return await new Promise((resolvePromise, reject) => {
48
78
  child.once("error", reject);
49
79
  child.once("exit", (exitCode) => resolvePromise(exitCode ?? 1));
50
80
  });
51
- process.exitCode = code;
52
81
  } finally {
53
82
  process.off("SIGINT", ignoreSignal);
54
83
  process.off("SIGBREAK", ignoreSignal);
@@ -69,5 +98,5 @@ if (process.argv[1]) {
69
98
  export {
70
99
  cliMainArguments,
71
100
  launchCli,
72
- needsWindowsMaglevWorkaround
101
+ needsRelaunch
73
102
  };
@@ -67,6 +67,13 @@ export type ContextForkOptions = Partial<Pick<ContextManagerOptions, "summarize"
67
67
  export { estimateTokens } from "./compaction.js";
68
68
  export declare class ContextManager {
69
69
  #private;
70
+ /**
71
+ * The visibility audit log persists every transient system admission and is
72
+ * serialized in full on every session save. Bound both dimensions or a long
73
+ * subagent-driven run grows it into hundreds of megabytes (heap OOM).
74
+ */
75
+ static readonly VISIBILITY_LOG_MAX_ENTRIES = 1000;
76
+ static readonly VISIBILITY_RECORD_CONTENT_LIMIT = 2048;
70
77
  constructor(options: ContextManagerOptions);
71
78
  clear(): void;
72
79
  /**