flavor-code 1.3.23 → 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 (181) hide show
  1. package/README.md +439 -434
  2. package/README.zh-CN.md +436 -431
  3. package/dist/agent/loop.d.ts +7 -2
  4. package/dist/{app-NTEUPJKJ.js → app-SMIB6P23.js} +82 -161
  5. package/dist/{chunk-Z62P4LL7.js → chunk-BYHO2CA5.js} +10412 -8712
  6. package/dist/{chunk-RPFWB45Y.js → chunk-EXOSMO57.js} +13 -8
  7. package/dist/chunk-N5MXHJKD.js +107 -0
  8. package/dist/{chunk-7OICVL2M.js → chunk-RAYH6K2H.js} +2 -44
  9. package/dist/{chunk-VEUSROUQ.js → chunk-UO4DLWU5.js} +8 -2
  10. package/dist/{chunk-SUSLIHXO.js → chunk-XMRKRPNC.js} +179 -14253
  11. package/dist/{chunk-RQTYHUMK.js → chunk-ZJCAQXA7.js} +17 -1
  12. package/dist/{claude-ink-6CEG2XZZ.js → claude-ink-6EZHF64C.js} +2 -3
  13. package/dist/cli-main.js +75 -28
  14. package/dist/cli.js +54 -10
  15. package/dist/config/load.d.ts +2 -0
  16. package/dist/config/schema.d.ts +8 -0
  17. package/dist/context/manager.d.ts +9 -0
  18. package/dist/desktop/main.js +3035 -1237
  19. package/dist/desktop-renderer/assets/index-Bk6FYhyh.css +1 -0
  20. package/dist/desktop-renderer/assets/index-RNe5Gtum.js +154 -0
  21. package/dist/desktop-renderer/assets/{interactive-terminal-CTFo4fK9.js → interactive-terminal-DestMQ2z.js} +1 -1
  22. package/dist/desktop-renderer/index.html +2 -2
  23. package/dist/doctor.d.ts +38 -0
  24. package/dist/execution/docker.d.ts +5 -1
  25. package/dist/execution/types.d.ts +11 -0
  26. package/dist/git/service.d.ts +3 -3
  27. package/dist/git/tools.d.ts +1 -1
  28. package/dist/goal/classifier.d.ts +2 -0
  29. package/dist/goal/orchestrator.d.ts +23 -2
  30. package/dist/goal/planner.d.ts +2 -0
  31. package/dist/goal/store.d.ts +2 -0
  32. package/dist/goal/types.d.ts +14 -0
  33. package/dist/harness/journal.d.ts +2 -0
  34. package/dist/harness/local.d.ts +2 -0
  35. package/dist/init/project.d.ts +0 -6
  36. package/dist/jobs/registry.d.ts +8 -1
  37. package/dist/{load-4FWNXE6F.js → load-EW56Q2MM.js} +1 -1
  38. package/dist/loop/orchestrator.d.ts +20 -0
  39. package/dist/loop/types.d.ts +7 -0
  40. package/dist/loop/verifier.d.ts +2 -0
  41. package/dist/models/openai.d.ts +1 -1
  42. package/dist/models/structured.d.ts +7 -0
  43. package/dist/models/types.d.ts +1 -1
  44. package/dist/production.d.ts +17 -0
  45. package/dist/sdk/index.js +5 -5
  46. package/dist/session/tree.d.ts +2 -0
  47. package/dist/tools/lsp.d.ts +15 -10
  48. package/dist/tools/runtime.d.ts +2 -1
  49. package/dist/tools/search.d.ts +1 -0
  50. package/dist/tools/shell.d.ts +17 -12
  51. package/dist/tools/types.d.ts +2 -1
  52. package/dist/ui/commands.d.ts +1 -1
  53. package/dist/ui/session.d.ts +12 -0
  54. package/dist/ui/transcript.d.ts +9 -0
  55. package/dist/update/check.d.ts +20 -0
  56. package/dist/utils/abort.d.ts +20 -0
  57. package/dist/utils/execFileNoThrow.d.ts +1 -0
  58. package/dist/utils/heap.d.ts +58 -0
  59. package/dist/utils/memory-restart.d.ts +42 -3
  60. package/dist/utils/process-tree.d.ts +2 -0
  61. package/dist/utils/rotation-census.d.ts +36 -0
  62. package/dist/utils/semver.d.ts +3 -0
  63. package/dist/utils/spawn-executable.d.ts +2 -0
  64. package/package.json +3 -2
  65. package//346/212/200/346/234/257/346/226/271/346/241/210/346/212/245/345/221/212.md +5848 -5848
  66. package/dist/astgraph/db.mjs +0 -237
  67. package/dist/astgraph/extract.mjs +0 -239
  68. package/dist/astgraph/flavor-plugin.json +0 -25
  69. package/dist/astgraph/grammars.mjs +0 -68
  70. package/dist/astgraph/index.js +0 -301
  71. package/dist/astgraph/indexer.mjs +0 -175
  72. package/dist/astgraph/query.mjs +0 -165
  73. package/dist/astgraph/resolve.mjs +0 -93
  74. package/dist/astgraph/vendor/tree-sitter-javascript.wasm +0 -0
  75. package/dist/astgraph/vendor/tree-sitter-tsx.wasm +0 -0
  76. package/dist/astgraph/vendor/tree-sitter-typescript.wasm +0 -0
  77. package/dist/astgraph/vendor/tree-sitter.js +0 -3980
  78. package/dist/astgraph/vendor/tree-sitter.wasm +0 -0
  79. package/dist/astgraph/vendor/zod/LICENSE +0 -21
  80. package/dist/astgraph/vendor/zod/index.js +0 -4
  81. package/dist/astgraph/vendor/zod/locales/index.js +0 -1
  82. package/dist/astgraph/vendor/zod/locales/package.json +0 -7
  83. package/dist/astgraph/vendor/zod/package.json +0 -135
  84. package/dist/astgraph/vendor/zod/v4/classic/checks.js +0 -1
  85. package/dist/astgraph/vendor/zod/v4/classic/coerce.js +0 -17
  86. package/dist/astgraph/vendor/zod/v4/classic/compat.js +0 -31
  87. package/dist/astgraph/vendor/zod/v4/classic/errors.js +0 -48
  88. package/dist/astgraph/vendor/zod/v4/classic/external.js +0 -20
  89. package/dist/astgraph/vendor/zod/v4/classic/from-json-schema.js +0 -599
  90. package/dist/astgraph/vendor/zod/v4/classic/index.js +0 -4
  91. package/dist/astgraph/vendor/zod/v4/classic/iso.js +0 -30
  92. package/dist/astgraph/vendor/zod/v4/classic/package.json +0 -7
  93. package/dist/astgraph/vendor/zod/v4/classic/parse.js +0 -15
  94. package/dist/astgraph/vendor/zod/v4/classic/schemas.js +0 -1395
  95. package/dist/astgraph/vendor/zod/v4/core/api.js +0 -1087
  96. package/dist/astgraph/vendor/zod/v4/core/checks.js +0 -575
  97. package/dist/astgraph/vendor/zod/v4/core/core.js +0 -78
  98. package/dist/astgraph/vendor/zod/v4/core/doc.js +0 -35
  99. package/dist/astgraph/vendor/zod/v4/core/errors.js +0 -185
  100. package/dist/astgraph/vendor/zod/v4/core/index.js +0 -16
  101. package/dist/astgraph/vendor/zod/v4/core/json-schema-generator.js +0 -95
  102. package/dist/astgraph/vendor/zod/v4/core/json-schema-processors.js +0 -601
  103. package/dist/astgraph/vendor/zod/v4/core/json-schema.js +0 -1
  104. package/dist/astgraph/vendor/zod/v4/core/package.json +0 -7
  105. package/dist/astgraph/vendor/zod/v4/core/parse.js +0 -93
  106. package/dist/astgraph/vendor/zod/v4/core/regexes.js +0 -139
  107. package/dist/astgraph/vendor/zod/v4/core/registries.js +0 -51
  108. package/dist/astgraph/vendor/zod/v4/core/schemas.js +0 -2239
  109. package/dist/astgraph/vendor/zod/v4/core/standard-schema.js +0 -1
  110. package/dist/astgraph/vendor/zod/v4/core/to-json-schema.js +0 -448
  111. package/dist/astgraph/vendor/zod/v4/core/util.js +0 -674
  112. package/dist/astgraph/vendor/zod/v4/core/versions.js +0 -5
  113. package/dist/astgraph/vendor/zod/v4/index.js +0 -3
  114. package/dist/astgraph/vendor/zod/v4/locales/ar.js +0 -106
  115. package/dist/astgraph/vendor/zod/v4/locales/az.js +0 -105
  116. package/dist/astgraph/vendor/zod/v4/locales/be.js +0 -156
  117. package/dist/astgraph/vendor/zod/v4/locales/bg.js +0 -120
  118. package/dist/astgraph/vendor/zod/v4/locales/ca.js +0 -107
  119. package/dist/astgraph/vendor/zod/v4/locales/cs.js +0 -111
  120. package/dist/astgraph/vendor/zod/v4/locales/da.js +0 -115
  121. package/dist/astgraph/vendor/zod/v4/locales/de.js +0 -108
  122. package/dist/astgraph/vendor/zod/v4/locales/el.js +0 -109
  123. package/dist/astgraph/vendor/zod/v4/locales/en.js +0 -113
  124. package/dist/astgraph/vendor/zod/v4/locales/eo.js +0 -109
  125. package/dist/astgraph/vendor/zod/v4/locales/es.js +0 -132
  126. package/dist/astgraph/vendor/zod/v4/locales/fa.js +0 -114
  127. package/dist/astgraph/vendor/zod/v4/locales/fi.js +0 -112
  128. package/dist/astgraph/vendor/zod/v4/locales/fr-CA.js +0 -107
  129. package/dist/astgraph/vendor/zod/v4/locales/fr.js +0 -125
  130. package/dist/astgraph/vendor/zod/v4/locales/he.js +0 -214
  131. package/dist/astgraph/vendor/zod/v4/locales/hr.js +0 -122
  132. package/dist/astgraph/vendor/zod/v4/locales/hu.js +0 -108
  133. package/dist/astgraph/vendor/zod/v4/locales/hy.js +0 -147
  134. package/dist/astgraph/vendor/zod/v4/locales/id.js +0 -106
  135. package/dist/astgraph/vendor/zod/v4/locales/index.js +0 -52
  136. package/dist/astgraph/vendor/zod/v4/locales/is.js +0 -109
  137. package/dist/astgraph/vendor/zod/v4/locales/it.js +0 -108
  138. package/dist/astgraph/vendor/zod/v4/locales/ja.js +0 -107
  139. package/dist/astgraph/vendor/zod/v4/locales/ka.js +0 -112
  140. package/dist/astgraph/vendor/zod/v4/locales/kh.js +0 -5
  141. package/dist/astgraph/vendor/zod/v4/locales/km.js +0 -110
  142. package/dist/astgraph/vendor/zod/v4/locales/ko.js +0 -111
  143. package/dist/astgraph/vendor/zod/v4/locales/lt.js +0 -203
  144. package/dist/astgraph/vendor/zod/v4/locales/mk.js +0 -109
  145. package/dist/astgraph/vendor/zod/v4/locales/ms.js +0 -107
  146. package/dist/astgraph/vendor/zod/v4/locales/nl.js +0 -110
  147. package/dist/astgraph/vendor/zod/v4/locales/no.js +0 -108
  148. package/dist/astgraph/vendor/zod/v4/locales/ota.js +0 -109
  149. package/dist/astgraph/vendor/zod/v4/locales/package.json +0 -7
  150. package/dist/astgraph/vendor/zod/v4/locales/pl.js +0 -109
  151. package/dist/astgraph/vendor/zod/v4/locales/ps.js +0 -114
  152. package/dist/astgraph/vendor/zod/v4/locales/pt.js +0 -108
  153. package/dist/astgraph/vendor/zod/v4/locales/ro.js +0 -119
  154. package/dist/astgraph/vendor/zod/v4/locales/ru.js +0 -156
  155. package/dist/astgraph/vendor/zod/v4/locales/sl.js +0 -109
  156. package/dist/astgraph/vendor/zod/v4/locales/sv.js +0 -110
  157. package/dist/astgraph/vendor/zod/v4/locales/ta.js +0 -110
  158. package/dist/astgraph/vendor/zod/v4/locales/th.js +0 -110
  159. package/dist/astgraph/vendor/zod/v4/locales/tr.js +0 -105
  160. package/dist/astgraph/vendor/zod/v4/locales/ua.js +0 -5
  161. package/dist/astgraph/vendor/zod/v4/locales/uk.js +0 -108
  162. package/dist/astgraph/vendor/zod/v4/locales/ur.js +0 -110
  163. package/dist/astgraph/vendor/zod/v4/locales/uz.js +0 -110
  164. package/dist/astgraph/vendor/zod/v4/locales/vi.js +0 -108
  165. package/dist/astgraph/vendor/zod/v4/locales/yo.js +0 -107
  166. package/dist/astgraph/vendor/zod/v4/locales/zh-CN.js +0 -109
  167. package/dist/astgraph/vendor/zod/v4/locales/zh-TW.js +0 -107
  168. package/dist/astgraph/vendor/zod/v4/mini/checks.js +0 -1
  169. package/dist/astgraph/vendor/zod/v4/mini/coerce.js +0 -22
  170. package/dist/astgraph/vendor/zod/v4/mini/external.js +0 -14
  171. package/dist/astgraph/vendor/zod/v4/mini/index.js +0 -3
  172. package/dist/astgraph/vendor/zod/v4/mini/iso.js +0 -34
  173. package/dist/astgraph/vendor/zod/v4/mini/package.json +0 -7
  174. package/dist/astgraph/vendor/zod/v4/mini/parse.js +0 -1
  175. package/dist/astgraph/vendor/zod/v4/mini/schemas.js +0 -961
  176. package/dist/astgraph/vendor/zod/v4/package.json +0 -7
  177. package/dist/chunk-CIVPKHF4.js +0 -53
  178. package/dist/chunk-OTYFL4AG.js +0 -16
  179. package/dist/desktop-renderer/assets/index-D75ozXnZ.js +0 -154
  180. package/dist/desktop-renderer/assets/index-ZZsUx916.css +0 -1
  181. 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,
@@ -86,6 +87,18 @@ var AuditLogger = class {
86
87
  }
87
88
  };
88
89
 
90
+ // src/utils/semver.ts
91
+ import { gt as semverGt, gte as semverGte, valid as semverValid } from "semver";
92
+ function gte(a, b) {
93
+ return semverGte(a, b, { loose: true });
94
+ }
95
+ function gt(a, b) {
96
+ return semverGt(a, b, { loose: true });
97
+ }
98
+ function isValidVersion(value) {
99
+ return semverValid(value, { loose: true }) !== null;
100
+ }
101
+
89
102
  // src/utils/intl.ts
90
103
  var graphemeSegmenter;
91
104
  function getGraphemeSegmenter() {
@@ -147,6 +160,9 @@ export {
147
160
  currentUsageSession,
148
161
  appendUsageLog,
149
162
  AuditLogger,
163
+ gte,
164
+ gt,
165
+ isValidVersion,
150
166
  getGraphemeSegmenter,
151
167
  resolveLanguage,
152
168
  languageInstruction
@@ -10,9 +10,8 @@ import {
10
10
  useStdout,
11
11
  use_app_default,
12
12
  use_input_default
13
- } from "./chunk-SUSLIHXO.js";
14
- import "./chunk-OTYFL4AG.js";
15
- import "./chunk-RQTYHUMK.js";
13
+ } from "./chunk-XMRKRPNC.js";
14
+ import "./chunk-ZJCAQXA7.js";
16
15
  import "./chunk-S32JRDZK.js";
17
16
  export {
18
17
  AlternateScreen,
package/dist/cli-main.js CHANGED
@@ -3,32 +3,36 @@ import { createRequire } from "node:module"; const require = createRequire(impor
3
3
  import {
4
4
  FlavorRpcServer,
5
5
  TraceRecorder
6
- } from "./chunk-VEUSROUQ.js";
6
+ } from "./chunk-UO4DLWU5.js";
7
7
  import {
8
- NPM_PACKAGE_NAME,
9
- fetchLatestVersion,
10
8
  staticTaskLines
11
- } from "./chunk-7OICVL2M.js";
9
+ } from "./chunk-RAYH6K2H.js";
12
10
  import {
13
11
  DEFAULT_MAX_OUTPUT_BYTES,
14
12
  MAX_ALIAS_LENGTH,
15
13
  MEMORY_TYPES,
16
14
  MemoryStore,
15
+ NPM_PACKAGE_NAME,
17
16
  PluginManifestSchema,
18
17
  SkillRegistry,
19
18
  classifyMemoryHeat,
20
19
  createExecutionEnvironment,
21
20
  createProductionRuntime,
22
21
  executeShell,
22
+ fetchLatestVersion,
23
+ formatDoctorReport,
23
24
  initializeFlavor,
24
25
  installCrashGuard,
25
26
  message,
26
27
  packageVersion,
27
28
  prepareSpawnInvocation,
28
29
  redactErrorText,
30
+ runDoctor,
29
31
  runPalBroker
30
- } from "./chunk-Z62P4LL7.js";
31
- import "./chunk-CIVPKHF4.js";
32
+ } from "./chunk-BYHO2CA5.js";
33
+ import {
34
+ MEMORY_RESTART_EXIT_CODE
35
+ } from "./chunk-N5MXHJKD.js";
32
36
  import {
33
37
  McpServerConfigSchema,
34
38
  McpServerNameSchema,
@@ -37,12 +41,11 @@ import {
37
41
  readRecoverableFile,
38
42
  setProjectSkillDisabled,
39
43
  updateProtectedFile
40
- } from "./chunk-RPFWB45Y.js";
44
+ } from "./chunk-EXOSMO57.js";
41
45
  import {
42
46
  gt,
43
47
  isValidVersion
44
- } from "./chunk-OTYFL4AG.js";
45
- import "./chunk-RQTYHUMK.js";
48
+ } from "./chunk-ZJCAQXA7.js";
46
49
  import "./chunk-S32JRDZK.js";
47
50
 
48
51
  // src/cli.tsx
@@ -82,6 +85,25 @@ async function runUpdate(options = {}) {
82
85
  return exitCode === 0 ? { status: "updated", current, latest } : { status: "install-failed", current, latest, exitCode };
83
86
  }
84
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
+
85
107
  // src/skills/manager.ts
86
108
  import { lstat, mkdir, readFile, readdir, realpath, rm, writeFile } from "fs/promises";
87
109
  import { homedir } from "os";
@@ -727,7 +749,7 @@ async function runEvaluationFile(path, outputPath) {
727
749
  })),
728
750
  ...parsed.maxTokens === void 0 ? {} : { maxTokens: parsed.maxTokens }
729
751
  };
730
- const configured = await import("./load-4FWNXE6F.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 }));
731
753
  const environment = createExecutionEnvironment(workspace, configured.config.execution) ?? new LocalExecutionEnvironment();
732
754
  let report;
733
755
  try {
@@ -751,7 +773,7 @@ async function runEvaluationFile(path, outputPath) {
751
773
 
752
774
  // src/cli.tsx
753
775
  function createProgram(dependencies = {}) {
754
- 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());
755
777
  program.command("init [directory]").description("Initialize Flavor project files in a directory (defaults to cwd)").action(async (directory) => {
756
778
  const cwd = directory ? resolve3(directory) : process.cwd();
757
779
  try {
@@ -788,6 +810,21 @@ function createProgram(dependencies = {}) {
788
810
  }
789
811
  } catch (error) {
790
812
  process.stderr.write(`update: ${safeError(error)}
813
+ `);
814
+ process.exitCode = 1;
815
+ }
816
+ });
817
+ program.command("doctor [directory]").description("Diagnose the local Flavor runtime, configuration, tools, plugins, and npm access").option("--json", "print the report as JSON").action(async (directory, command) => {
818
+ try {
819
+ const report = await (dependencies.runDoctor ?? runDoctor)({
820
+ workspace: resolve3(directory ?? process.cwd()),
821
+ home: homedir3()
822
+ });
823
+ process.stdout.write(command.json ? `${JSON.stringify(report, null, 2)}
824
+ ` : formatDoctorReport(report));
825
+ if (!report.ok) process.exitCode = 1;
826
+ } catch (error) {
827
+ process.stderr.write(`doctor: ${safeError(error)}
791
828
  `);
792
829
  process.exitCode = 1;
793
830
  }
@@ -853,7 +890,7 @@ function createProgram(dependencies = {}) {
853
890
  return;
854
891
  }
855
892
  if (options.print !== void 0) {
856
- process.exitCode = await runPrint(options.print, {}, resumeSession);
893
+ process.exitCode = await runPrint(options.print, {}, resumeSession, options.memoryRestart === true);
857
894
  return;
858
895
  }
859
896
  if (!(dependencies.isTTY?.() ?? process.stdin.isTTY)) {
@@ -879,17 +916,22 @@ function createProgram(dependencies = {}) {
879
916
  return program;
880
917
  }
881
918
  async function runInteractiveCli(props) {
882
- const [{ render, AlternateScreen }, { createElement }, { App }] = await Promise.all([
883
- import("./claude-ink-6CEG2XZZ.js"),
884
- import("react"),
885
- import("./app-NTEUPJKJ.js")
886
- ]);
887
- const instance = await render(createElement(
888
- AlternateScreen,
889
- { mouseTracking: true },
890
- createElement(App, props)
891
- ), { exitOnCtrlC: false });
892
- 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
+ }
893
935
  }
894
936
  function parsePalAlias(value) {
895
937
  const alias = value.trim();
@@ -945,7 +987,7 @@ async function runRpcMode(options) {
945
987
  });
946
988
  await server.start();
947
989
  await recorder?.close();
948
- return 0;
990
+ return process.exitCode === MEMORY_RESTART_EXIT_CODE ? MEMORY_RESTART_EXIT_CODE : 0;
949
991
  } catch (error) {
950
992
  await recorder?.close().catch(() => void 0);
951
993
  process.stderr.write(`rpc: ${safeError(error)}
@@ -956,7 +998,7 @@ async function runRpcMode(options) {
956
998
  function setInteractiveProcessTitle(target = process) {
957
999
  target.title = "Flavor Code";
958
1000
  }
959
- async function runPrint(prompt, dependencies = {}, resumeSession) {
1001
+ async function runPrint(prompt, dependencies = {}, resumeSession, memoryRestart = false) {
960
1002
  let code = 0;
961
1003
  let runtime;
962
1004
  const stdout = dependencies.stdout ?? ((text) => process.stdout.write(text));
@@ -988,7 +1030,11 @@ async function runPrint(prompt, dependencies = {}, resumeSession) {
988
1030
  }
989
1031
  try {
990
1032
  await runtime.session.start();
991
- 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
+ }
992
1038
  } catch (error) {
993
1039
  stderr(`runtime: ${safeError(error)}
994
1040
  `);
@@ -1009,8 +1055,9 @@ async function runPrint(prompt, dependencies = {}, resumeSession) {
1009
1055
  code = 1;
1010
1056
  }
1011
1057
  }
1012
- if (code === 0) stdout("\n");
1013
- 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;
1014
1061
  }
1015
1062
  function safeError(error) {
1016
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);
@@ -5,6 +5,8 @@ export interface LoadConfigOptions {
5
5
  home: string;
6
6
  cli?: ConfigObject;
7
7
  environment?: Record<string, string | undefined>;
8
+ /** Disable environment persistence for read-only diagnostics. */
9
+ seedGlobalEnv?: boolean;
8
10
  }
9
11
  export interface LoadedConfig {
10
12
  config: FlavorConfig;
@@ -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;