flavor-code 1.4.0-beta.1 → 1.4.0-beta.10

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.
Files changed (169) hide show
  1. package/README.md +2 -0
  2. package/README.zh-CN.md +2 -0
  3. package/dist/agent/loop.d.ts +7 -2
  4. package/dist/{app-C5ZQUOKJ.js → app-SMIB6P23.js} +44 -11
  5. package/dist/{chunk-6MNOZ2TX.js → chunk-BYHO2CA5.js} +1925 -765
  6. package/dist/{chunk-URUVFECH.js → chunk-EXOSMO57.js} +12 -7
  7. package/dist/chunk-N5MXHJKD.js +107 -0
  8. package/dist/{chunk-2BF7CVWZ.js → chunk-RAYH6K2H.js} +2 -2
  9. package/dist/{chunk-FOTMP4ZS.js → chunk-UO4DLWU5.js} +8 -2
  10. package/dist/{chunk-ODRWR4KK.js → chunk-XMRKRPNC.js} +179 -14253
  11. package/dist/{chunk-3WCDZ6ZL.js → chunk-ZJCAQXA7.js} +2 -1
  12. package/dist/{claude-ink-LP32NSX5.js → claude-ink-6EZHF64C.js} +2 -2
  13. package/dist/cli-main.js +56 -25
  14. package/dist/cli.js +54 -10
  15. package/dist/config/schema.d.ts +8 -0
  16. package/dist/context/manager.d.ts +9 -0
  17. package/dist/desktop/main.js +2318 -1071
  18. package/dist/desktop-renderer/assets/index-RNe5Gtum.js +154 -0
  19. package/dist/desktop-renderer/assets/{interactive-terminal-C4o7MNPO.js → interactive-terminal-DestMQ2z.js} +1 -1
  20. package/dist/desktop-renderer/index.html +1 -1
  21. package/dist/git/service.d.ts +3 -3
  22. package/dist/git/tools.d.ts +1 -1
  23. package/dist/goal/classifier.d.ts +2 -0
  24. package/dist/goal/orchestrator.d.ts +23 -2
  25. package/dist/goal/planner.d.ts +2 -0
  26. package/dist/goal/store.d.ts +2 -0
  27. package/dist/goal/types.d.ts +14 -0
  28. package/dist/harness/journal.d.ts +2 -0
  29. package/dist/harness/local.d.ts +2 -0
  30. package/dist/init/project.d.ts +0 -6
  31. package/dist/jobs/registry.d.ts +7 -1
  32. package/dist/{load-V2UIYYQI.js → load-EW56Q2MM.js} +1 -1
  33. package/dist/loop/orchestrator.d.ts +20 -0
  34. package/dist/loop/types.d.ts +7 -0
  35. package/dist/loop/verifier.d.ts +2 -0
  36. package/dist/models/openai.d.ts +1 -1
  37. package/dist/models/structured.d.ts +7 -0
  38. package/dist/models/types.d.ts +1 -1
  39. package/dist/production.d.ts +17 -0
  40. package/dist/sdk/index.js +5 -5
  41. package/dist/session/tree.d.ts +2 -0
  42. package/dist/tools/lsp.d.ts +15 -10
  43. package/dist/tools/runtime.d.ts +2 -1
  44. package/dist/tools/search.d.ts +1 -0
  45. package/dist/tools/types.d.ts +1 -1
  46. package/dist/ui/session.d.ts +11 -0
  47. package/dist/ui/transcript.d.ts +9 -0
  48. package/dist/utils/abort.d.ts +20 -0
  49. package/dist/utils/execFileNoThrow.d.ts +1 -0
  50. package/dist/utils/heap.d.ts +58 -0
  51. package/dist/utils/memory-restart.d.ts +42 -3
  52. package/dist/utils/process-tree.d.ts +2 -0
  53. package/dist/utils/rotation-census.d.ts +36 -0
  54. package/package.json +3 -2
  55. package//346/212/200/346/234/257/346/226/271/346/241/210/346/212/245/345/221/212.md +7 -7
  56. package/dist/astgraph/db.mjs +0 -237
  57. package/dist/astgraph/extract.mjs +0 -239
  58. package/dist/astgraph/flavor-plugin.json +0 -25
  59. package/dist/astgraph/grammars.mjs +0 -68
  60. package/dist/astgraph/index.js +0 -301
  61. package/dist/astgraph/indexer.mjs +0 -175
  62. package/dist/astgraph/query.mjs +0 -165
  63. package/dist/astgraph/resolve.mjs +0 -93
  64. package/dist/astgraph/vendor/tree-sitter-javascript.wasm +0 -0
  65. package/dist/astgraph/vendor/tree-sitter-tsx.wasm +0 -0
  66. package/dist/astgraph/vendor/tree-sitter-typescript.wasm +0 -0
  67. package/dist/astgraph/vendor/tree-sitter.js +0 -3980
  68. package/dist/astgraph/vendor/tree-sitter.wasm +0 -0
  69. package/dist/astgraph/vendor/zod/LICENSE +0 -21
  70. package/dist/astgraph/vendor/zod/index.js +0 -4
  71. package/dist/astgraph/vendor/zod/locales/index.js +0 -1
  72. package/dist/astgraph/vendor/zod/locales/package.json +0 -7
  73. package/dist/astgraph/vendor/zod/package.json +0 -135
  74. package/dist/astgraph/vendor/zod/v4/classic/checks.js +0 -1
  75. package/dist/astgraph/vendor/zod/v4/classic/coerce.js +0 -17
  76. package/dist/astgraph/vendor/zod/v4/classic/compat.js +0 -31
  77. package/dist/astgraph/vendor/zod/v4/classic/errors.js +0 -48
  78. package/dist/astgraph/vendor/zod/v4/classic/external.js +0 -20
  79. package/dist/astgraph/vendor/zod/v4/classic/from-json-schema.js +0 -599
  80. package/dist/astgraph/vendor/zod/v4/classic/index.js +0 -4
  81. package/dist/astgraph/vendor/zod/v4/classic/iso.js +0 -30
  82. package/dist/astgraph/vendor/zod/v4/classic/package.json +0 -7
  83. package/dist/astgraph/vendor/zod/v4/classic/parse.js +0 -15
  84. package/dist/astgraph/vendor/zod/v4/classic/schemas.js +0 -1395
  85. package/dist/astgraph/vendor/zod/v4/core/api.js +0 -1087
  86. package/dist/astgraph/vendor/zod/v4/core/checks.js +0 -575
  87. package/dist/astgraph/vendor/zod/v4/core/core.js +0 -78
  88. package/dist/astgraph/vendor/zod/v4/core/doc.js +0 -35
  89. package/dist/astgraph/vendor/zod/v4/core/errors.js +0 -185
  90. package/dist/astgraph/vendor/zod/v4/core/index.js +0 -16
  91. package/dist/astgraph/vendor/zod/v4/core/json-schema-generator.js +0 -95
  92. package/dist/astgraph/vendor/zod/v4/core/json-schema-processors.js +0 -601
  93. package/dist/astgraph/vendor/zod/v4/core/json-schema.js +0 -1
  94. package/dist/astgraph/vendor/zod/v4/core/package.json +0 -7
  95. package/dist/astgraph/vendor/zod/v4/core/parse.js +0 -93
  96. package/dist/astgraph/vendor/zod/v4/core/regexes.js +0 -139
  97. package/dist/astgraph/vendor/zod/v4/core/registries.js +0 -51
  98. package/dist/astgraph/vendor/zod/v4/core/schemas.js +0 -2239
  99. package/dist/astgraph/vendor/zod/v4/core/standard-schema.js +0 -1
  100. package/dist/astgraph/vendor/zod/v4/core/to-json-schema.js +0 -448
  101. package/dist/astgraph/vendor/zod/v4/core/util.js +0 -674
  102. package/dist/astgraph/vendor/zod/v4/core/versions.js +0 -5
  103. package/dist/astgraph/vendor/zod/v4/index.js +0 -3
  104. package/dist/astgraph/vendor/zod/v4/locales/ar.js +0 -106
  105. package/dist/astgraph/vendor/zod/v4/locales/az.js +0 -105
  106. package/dist/astgraph/vendor/zod/v4/locales/be.js +0 -156
  107. package/dist/astgraph/vendor/zod/v4/locales/bg.js +0 -120
  108. package/dist/astgraph/vendor/zod/v4/locales/ca.js +0 -107
  109. package/dist/astgraph/vendor/zod/v4/locales/cs.js +0 -111
  110. package/dist/astgraph/vendor/zod/v4/locales/da.js +0 -115
  111. package/dist/astgraph/vendor/zod/v4/locales/de.js +0 -108
  112. package/dist/astgraph/vendor/zod/v4/locales/el.js +0 -109
  113. package/dist/astgraph/vendor/zod/v4/locales/en.js +0 -113
  114. package/dist/astgraph/vendor/zod/v4/locales/eo.js +0 -109
  115. package/dist/astgraph/vendor/zod/v4/locales/es.js +0 -132
  116. package/dist/astgraph/vendor/zod/v4/locales/fa.js +0 -114
  117. package/dist/astgraph/vendor/zod/v4/locales/fi.js +0 -112
  118. package/dist/astgraph/vendor/zod/v4/locales/fr-CA.js +0 -107
  119. package/dist/astgraph/vendor/zod/v4/locales/fr.js +0 -125
  120. package/dist/astgraph/vendor/zod/v4/locales/he.js +0 -214
  121. package/dist/astgraph/vendor/zod/v4/locales/hr.js +0 -122
  122. package/dist/astgraph/vendor/zod/v4/locales/hu.js +0 -108
  123. package/dist/astgraph/vendor/zod/v4/locales/hy.js +0 -147
  124. package/dist/astgraph/vendor/zod/v4/locales/id.js +0 -106
  125. package/dist/astgraph/vendor/zod/v4/locales/index.js +0 -52
  126. package/dist/astgraph/vendor/zod/v4/locales/is.js +0 -109
  127. package/dist/astgraph/vendor/zod/v4/locales/it.js +0 -108
  128. package/dist/astgraph/vendor/zod/v4/locales/ja.js +0 -107
  129. package/dist/astgraph/vendor/zod/v4/locales/ka.js +0 -112
  130. package/dist/astgraph/vendor/zod/v4/locales/kh.js +0 -5
  131. package/dist/astgraph/vendor/zod/v4/locales/km.js +0 -110
  132. package/dist/astgraph/vendor/zod/v4/locales/ko.js +0 -111
  133. package/dist/astgraph/vendor/zod/v4/locales/lt.js +0 -203
  134. package/dist/astgraph/vendor/zod/v4/locales/mk.js +0 -109
  135. package/dist/astgraph/vendor/zod/v4/locales/ms.js +0 -107
  136. package/dist/astgraph/vendor/zod/v4/locales/nl.js +0 -110
  137. package/dist/astgraph/vendor/zod/v4/locales/no.js +0 -108
  138. package/dist/astgraph/vendor/zod/v4/locales/ota.js +0 -109
  139. package/dist/astgraph/vendor/zod/v4/locales/package.json +0 -7
  140. package/dist/astgraph/vendor/zod/v4/locales/pl.js +0 -109
  141. package/dist/astgraph/vendor/zod/v4/locales/ps.js +0 -114
  142. package/dist/astgraph/vendor/zod/v4/locales/pt.js +0 -108
  143. package/dist/astgraph/vendor/zod/v4/locales/ro.js +0 -119
  144. package/dist/astgraph/vendor/zod/v4/locales/ru.js +0 -156
  145. package/dist/astgraph/vendor/zod/v4/locales/sl.js +0 -109
  146. package/dist/astgraph/vendor/zod/v4/locales/sv.js +0 -110
  147. package/dist/astgraph/vendor/zod/v4/locales/ta.js +0 -110
  148. package/dist/astgraph/vendor/zod/v4/locales/th.js +0 -110
  149. package/dist/astgraph/vendor/zod/v4/locales/tr.js +0 -105
  150. package/dist/astgraph/vendor/zod/v4/locales/ua.js +0 -5
  151. package/dist/astgraph/vendor/zod/v4/locales/uk.js +0 -108
  152. package/dist/astgraph/vendor/zod/v4/locales/ur.js +0 -110
  153. package/dist/astgraph/vendor/zod/v4/locales/uz.js +0 -110
  154. package/dist/astgraph/vendor/zod/v4/locales/vi.js +0 -108
  155. package/dist/astgraph/vendor/zod/v4/locales/yo.js +0 -107
  156. package/dist/astgraph/vendor/zod/v4/locales/zh-CN.js +0 -109
  157. package/dist/astgraph/vendor/zod/v4/locales/zh-TW.js +0 -107
  158. package/dist/astgraph/vendor/zod/v4/mini/checks.js +0 -1
  159. package/dist/astgraph/vendor/zod/v4/mini/coerce.js +0 -22
  160. package/dist/astgraph/vendor/zod/v4/mini/external.js +0 -14
  161. package/dist/astgraph/vendor/zod/v4/mini/index.js +0 -3
  162. package/dist/astgraph/vendor/zod/v4/mini/iso.js +0 -34
  163. package/dist/astgraph/vendor/zod/v4/mini/package.json +0 -7
  164. package/dist/astgraph/vendor/zod/v4/mini/parse.js +0 -1
  165. package/dist/astgraph/vendor/zod/v4/mini/schemas.js +0 -961
  166. package/dist/astgraph/vendor/zod/v4/package.json +0 -7
  167. package/dist/chunk-CIVPKHF4.js +0 -53
  168. package/dist/desktop-renderer/assets/index-CqRIr-hz.js +0 -154
  169. package/dist/devtools-4QTPKBKK.js +0 -2
@@ -10,7 +10,8 @@ function execFileNoThrow(file, args, options = {}) {
10
10
  cwd: options.useCwd === false ? void 0 : process.cwd(),
11
11
  env: options.env,
12
12
  encoding: "utf8",
13
- windowsHide: true
13
+ windowsHide: true,
14
+ ...options.signal === void 0 ? {} : { signal: options.signal }
14
15
  }, (error, stdout, stderr) => {
15
16
  resolve2({
16
17
  stdout,
@@ -10,8 +10,8 @@ import {
10
10
  useStdout,
11
11
  use_app_default,
12
12
  use_input_default
13
- } from "./chunk-ODRWR4KK.js";
14
- import "./chunk-3WCDZ6ZL.js";
13
+ } from "./chunk-XMRKRPNC.js";
14
+ import "./chunk-ZJCAQXA7.js";
15
15
  import "./chunk-S32JRDZK.js";
16
16
  export {
17
17
  AlternateScreen,
package/dist/cli-main.js CHANGED
@@ -3,10 +3,10 @@ import { createRequire } from "node:module"; const require = createRequire(impor
3
3
  import {
4
4
  FlavorRpcServer,
5
5
  TraceRecorder
6
- } from "./chunk-FOTMP4ZS.js";
6
+ } from "./chunk-UO4DLWU5.js";
7
7
  import {
8
8
  staticTaskLines
9
- } from "./chunk-2BF7CVWZ.js";
9
+ } from "./chunk-RAYH6K2H.js";
10
10
  import {
11
11
  DEFAULT_MAX_OUTPUT_BYTES,
12
12
  MAX_ALIAS_LENGTH,
@@ -29,8 +29,10 @@ import {
29
29
  redactErrorText,
30
30
  runDoctor,
31
31
  runPalBroker
32
- } from "./chunk-6MNOZ2TX.js";
33
- import "./chunk-CIVPKHF4.js";
32
+ } from "./chunk-BYHO2CA5.js";
33
+ import {
34
+ MEMORY_RESTART_EXIT_CODE
35
+ } from "./chunk-N5MXHJKD.js";
34
36
  import {
35
37
  McpServerConfigSchema,
36
38
  McpServerNameSchema,
@@ -39,11 +41,11 @@ import {
39
41
  readRecoverableFile,
40
42
  setProjectSkillDisabled,
41
43
  updateProtectedFile
42
- } from "./chunk-URUVFECH.js";
44
+ } from "./chunk-EXOSMO57.js";
43
45
  import {
44
46
  gt,
45
47
  isValidVersion
46
- } from "./chunk-3WCDZ6ZL.js";
48
+ } from "./chunk-ZJCAQXA7.js";
47
49
  import "./chunk-S32JRDZK.js";
48
50
 
49
51
  // src/cli.tsx
@@ -83,6 +85,25 @@ async function runUpdate(options = {}) {
83
85
  return exitCode === 0 ? { status: "updated", current, latest } : { status: "install-failed", current, latest, exitCode };
84
86
  }
85
87
 
88
+ // src/ui/user-timing.ts
89
+ import { performance } from "perf_hooks";
90
+ function clearUiUserTimingEntries() {
91
+ performance.clearMarks();
92
+ performance.clearMeasures();
93
+ }
94
+ function installUiUserTimingSweeper(intervalMs = 250) {
95
+ if (!Number.isSafeInteger(intervalMs) || intervalMs <= 0) {
96
+ throw new Error("User Timing sweep interval must be a positive integer");
97
+ }
98
+ clearUiUserTimingEntries();
99
+ const timer = setInterval(clearUiUserTimingEntries, intervalMs);
100
+ timer.unref();
101
+ return () => {
102
+ clearInterval(timer);
103
+ clearUiUserTimingEntries();
104
+ };
105
+ }
106
+
86
107
  // src/skills/manager.ts
87
108
  import { lstat, mkdir, readFile, readdir, realpath, rm, writeFile } from "fs/promises";
88
109
  import { homedir } from "os";
@@ -728,7 +749,7 @@ async function runEvaluationFile(path, outputPath) {
728
749
  })),
729
750
  ...parsed.maxTokens === void 0 ? {} : { maxTokens: parsed.maxTokens }
730
751
  };
731
- const configured = await import("./load-V2UIYYQI.js").then(({ loadConfig: loadConfig2 }) => loadConfig2({ cwd: workspace, home: process.env.USERPROFILE ?? process.env.HOME ?? workspace }));
752
+ const configured = await import("./load-EW56Q2MM.js").then(({ loadConfig: loadConfig2 }) => loadConfig2({ cwd: workspace, home: process.env.USERPROFILE ?? process.env.HOME ?? workspace }));
732
753
  const environment = createExecutionEnvironment(workspace, configured.config.execution) ?? new LocalExecutionEnvironment();
733
754
  let report;
734
755
  try {
@@ -752,7 +773,7 @@ async function runEvaluationFile(path, outputPath) {
752
773
 
753
774
  // src/cli.tsx
754
775
  function createProgram(dependencies = {}) {
755
- const program = new Command().name("flavor").description("Interactive coding agent").version(packageVersion()).option("-p, --print <prompt>", "run one prompt without the interactive UI").option("--resume [session-id]", "resume a saved session (latest when id is omitted)").option("--mode <mode>", "runtime mode: interactive or rpc").option("--workspace <path>", "workspace path (RPC mode)").option("--rpc-approvals", "allow an RPC client to resolve interactive tool approvals").option("--rpc-streamed-writes", "stream proposed file writes to an RPC client before committing them").option("--trace <path>", "write a redacted JSONL execution trace").option("--pal-name <alias>", "name this interactive Flavor instance for /pals and /chat").addOption(new Option("--pals-broker <address>").hideHelp());
776
+ const program = new Command().name("flavor").description("Interactive coding agent").version(packageVersion()).option("-p, --print <prompt>", "run one prompt without the interactive UI").option("--resume [session-id]", "resume a saved session (latest when id is omitted)").option("--mode <mode>", "runtime mode: interactive or rpc").option("--workspace <path>", "workspace path (RPC mode)").option("--rpc-approvals", "allow an RPC client to resolve interactive tool approvals").option("--rpc-streamed-writes", "stream proposed file writes to an RPC client before committing them").option("--trace <path>", "write a redacted JSONL execution trace").option("--pal-name <alias>", "name this interactive Flavor instance for /pals and /chat").addOption(new Option("--memory-restart").hideHelp()).addOption(new Option("--pals-broker <address>").hideHelp());
756
777
  program.command("init [directory]").description("Initialize Flavor project files in a directory (defaults to cwd)").action(async (directory) => {
757
778
  const cwd = directory ? resolve3(directory) : process.cwd();
758
779
  try {
@@ -869,7 +890,7 @@ function createProgram(dependencies = {}) {
869
890
  return;
870
891
  }
871
892
  if (options.print !== void 0) {
872
- process.exitCode = await runPrint(options.print, {}, resumeSession);
893
+ process.exitCode = await runPrint(options.print, {}, resumeSession, options.memoryRestart === true);
873
894
  return;
874
895
  }
875
896
  if (!(dependencies.isTTY?.() ?? process.stdin.isTTY)) {
@@ -895,17 +916,22 @@ function createProgram(dependencies = {}) {
895
916
  return program;
896
917
  }
897
918
  async function runInteractiveCli(props) {
898
- const [{ render, AlternateScreen }, { createElement }, { App }] = await Promise.all([
899
- import("./claude-ink-LP32NSX5.js"),
900
- import("react"),
901
- import("./app-C5ZQUOKJ.js")
902
- ]);
903
- const instance = await render(createElement(
904
- AlternateScreen,
905
- { mouseTracking: true },
906
- createElement(App, props)
907
- ), { exitOnCtrlC: false });
908
- await instance.waitUntilExit();
919
+ const disposeUserTimingSweeper = installUiUserTimingSweeper();
920
+ try {
921
+ const [{ render, AlternateScreen }, { createElement }, { App }] = await Promise.all([
922
+ import("./claude-ink-6EZHF64C.js"),
923
+ import("react"),
924
+ import("./app-SMIB6P23.js")
925
+ ]);
926
+ const instance = await render(createElement(
927
+ AlternateScreen,
928
+ { mouseTracking: true },
929
+ createElement(App, props)
930
+ ), { exitOnCtrlC: false });
931
+ await instance.waitUntilExit();
932
+ } finally {
933
+ disposeUserTimingSweeper();
934
+ }
909
935
  }
910
936
  function parsePalAlias(value) {
911
937
  const alias = value.trim();
@@ -961,7 +987,7 @@ async function runRpcMode(options) {
961
987
  });
962
988
  await server.start();
963
989
  await recorder?.close();
964
- return 0;
990
+ return process.exitCode === MEMORY_RESTART_EXIT_CODE ? MEMORY_RESTART_EXIT_CODE : 0;
965
991
  } catch (error) {
966
992
  await recorder?.close().catch(() => void 0);
967
993
  process.stderr.write(`rpc: ${safeError(error)}
@@ -972,7 +998,7 @@ async function runRpcMode(options) {
972
998
  function setInteractiveProcessTitle(target = process) {
973
999
  target.title = "Flavor Code";
974
1000
  }
975
- async function runPrint(prompt, dependencies = {}, resumeSession) {
1001
+ async function runPrint(prompt, dependencies = {}, resumeSession, memoryRestart = false) {
976
1002
  let code = 0;
977
1003
  let runtime;
978
1004
  const stdout = dependencies.stdout ?? ((text) => process.stdout.write(text));
@@ -1004,7 +1030,11 @@ async function runPrint(prompt, dependencies = {}, resumeSession) {
1004
1030
  }
1005
1031
  try {
1006
1032
  await runtime.session.start();
1007
- await runtime.session.submit(prompt);
1033
+ if (runtime.session.rotationContinuationResumed) {
1034
+ await runtime.session.whenIdle();
1035
+ } else if (!memoryRestart) {
1036
+ await runtime.session.submit(prompt);
1037
+ }
1008
1038
  } catch (error) {
1009
1039
  stderr(`runtime: ${safeError(error)}
1010
1040
  `);
@@ -1025,8 +1055,9 @@ async function runPrint(prompt, dependencies = {}, resumeSession) {
1025
1055
  code = 1;
1026
1056
  }
1027
1057
  }
1028
- if (code === 0) stdout("\n");
1029
- return code;
1058
+ const restarting = process.exitCode === MEMORY_RESTART_EXIT_CODE;
1059
+ if (code === 0 && !restarting) stdout("\n");
1060
+ return restarting ? MEMORY_RESTART_EXIT_CODE : code;
1030
1061
  }
1031
1062
  function safeError(error) {
1032
1063
  return redactErrorText(message(error));
package/dist/cli.js CHANGED
@@ -5,19 +5,25 @@ import {
5
5
  memoryRestartArgs,
6
6
  memoryRestartMarkerPath,
7
7
  parseMemoryRestartMarker
8
- } from "./chunk-CIVPKHF4.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
+ import { totalmem } from "os";
15
+ import { join } from "path";
14
16
  import { fileURLToPath } from "url";
15
17
  function needsRelaunch(runtime) {
16
18
  if (!runtime.execArgv.some((argument) => argument === "--report-on-fatalerror")) return true;
17
- return !runtime.execArgv.some((argument) => argument.startsWith("--heapsnapshot-near-heap-limit"));
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;
21
+ return !runtime.execArgv.some((argument) => argument === "--expose-gc");
18
22
  }
19
- function cliMainArguments(mainPath, argv) {
20
- return [
23
+ var HEAP_HEADROOM_MB = 8192;
24
+ var HEAP_HEADROOM_MIN_TOTALMEM = 12 * 1024 * 1024 * 1024;
25
+ function cliMainArguments(mainPath, argv, heapProfile) {
26
+ const flags = [
21
27
  // Fatal V8 errors (heap OOM, native crashes) bypass crash-guard.ts and
22
28
  // leave only an unusable native stack. Ask Node to dump a diagnostic
23
29
  // report next to the working directory so the next crash has a scene.
@@ -27,9 +33,33 @@ function cliMainArguments(mainPath, argv) {
27
33
  // Capture one heap snapshot as the heap nears its limit so the next
28
34
  // crash leaves a .heapsnapshot retainer trail next to the report.
29
35
  "--heapsnapshot-near-heap-limit=1",
30
- mainPath,
31
- ...argv
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",
42
+ // The heap watermarks are GC-verified: heapUsed counts uncollected
43
+ // garbage, and stopping turns or rotating on garbage alone would waste
44
+ // work. Exposing gc lets the watermark measure the live set instead.
45
+ "--expose-gc"
32
46
  ];
47
+ if (heapProfile !== void 0) {
48
+ flags.push(`--heap-prof-dir=${heapProfile.directory}`, `--heap-prof-name=${heapProfile.name}`);
49
+ }
50
+ const processHeapFlag = process.execArgv.find((argument) => argument.startsWith("--max-old-space-size"));
51
+ const argvHeapFlag = argv.find((argument) => argument.startsWith("--max-old-space-size"));
52
+ const userHeapFlag = processHeapFlag ?? argvHeapFlag;
53
+ if (userHeapFlag !== void 0) {
54
+ flags.push(userHeapFlag);
55
+ } else {
56
+ const constrained = process.constrainedMemory?.() ?? 0;
57
+ const availableLimit = constrained > 0 ? Math.min(totalmem(), constrained) : totalmem();
58
+ if (availableLimit >= HEAP_HEADROOM_MIN_TOTALMEM) {
59
+ flags.push(`--max-old-space-size=${HEAP_HEADROOM_MB}`);
60
+ }
61
+ }
62
+ return [...flags, mainPath, ...argv.filter((argument) => argument !== argvHeapFlag)];
33
63
  }
34
64
  async function launchCli() {
35
65
  const mainUrl = new URL("./cli-main.js", import.meta.url);
@@ -43,8 +73,19 @@ async function launchCli() {
43
73
  }
44
74
  const mainPath = fileURLToPath(mainUrl);
45
75
  let argv = process.argv.slice(2);
76
+ let childSequence = 0;
46
77
  for (; ; ) {
47
- 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
+ }
48
89
  if (code === MEMORY_RESTART_EXIT_CODE) {
49
90
  let marker;
50
91
  try {
@@ -67,8 +108,11 @@ async function launchCli() {
67
108
  return;
68
109
  }
69
110
  }
70
- async function spawnAndWait(mainPath, argv) {
71
- 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), {
113
+ stdio: "inherit",
114
+ env: { ...process.env, NODE_ENV: "production" }
115
+ });
72
116
  const ignoreSignal = () => {
73
117
  };
74
118
  process.on("SIGINT", ignoreSignal);
@@ -24,6 +24,8 @@ export declare const ProviderConfigSchema: z.ZodObject<{
24
24
  high: "high";
25
25
  low: "low";
26
26
  medium: "medium";
27
+ minimal: "minimal";
28
+ xhigh: "xhigh";
27
29
  }>>;
28
30
  claudeClient: z.ZodOptional<z.ZodBoolean>;
29
31
  apiType: z.ZodOptional<z.ZodEnum<{
@@ -79,6 +81,8 @@ export declare const FlavorConfigSchema: z.ZodObject<{
79
81
  high: "high";
80
82
  low: "low";
81
83
  medium: "medium";
84
+ minimal: "minimal";
85
+ xhigh: "xhigh";
82
86
  }>>;
83
87
  claudeClient: z.ZodOptional<z.ZodBoolean>;
84
88
  apiType: z.ZodOptional<z.ZodEnum<{
@@ -164,6 +168,10 @@ export declare const FlavorConfigSchema: z.ZodObject<{
164
168
  maxTokens: z.ZodDefault<z.ZodNumber>;
165
169
  isolation: z.ZodDefault<z.ZodLiteral<"auto">>;
166
170
  }, z.core.$strip>>;
171
+ goal: z.ZodPrefault<z.ZodObject<{
172
+ maxRounds: z.ZodDefault<z.ZodNumber>;
173
+ maxStallStreak: z.ZodDefault<z.ZodNumber>;
174
+ }, z.core.$strip>>;
167
175
  context: z.ZodPrefault<z.ZodObject<{
168
176
  windowTokens: z.ZodDefault<z.ZodNumber>;
169
177
  reservedOutputTokens: z.ZodDefault<z.ZodNumber>;
@@ -97,6 +97,15 @@ export declare class ContextManager {
97
97
  restore(snapshot: ContextSnapshot): void;
98
98
  messagesForModel(): ModelMessage[];
99
99
  estimatedTokens(): number;
100
+ /** Retained sizes for the rotation census: what this context holds right now. */
101
+ census(): {
102
+ messages: number;
103
+ messageChars: number;
104
+ visibilityEntries: number;
105
+ visibilityChars: number;
106
+ transientEntries: number;
107
+ transientChars: number;
108
+ };
100
109
  needsCompaction(): boolean;
101
110
  get lastRecordedInputTokens(): number | undefined;
102
111
  get consecutiveAutoCompactFailures(): number;