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
@@ -16,12 +16,18 @@ export interface ShellToolOptions {
16
16
  defaultTimeoutMs?: number;
17
17
  executionEnvironment?: ExecutionEnvironment;
18
18
  jobs?: JobRegistry;
19
+ environment?: NodeJS.ProcessEnv;
19
20
  }
20
21
  export interface TruncationMetadata {
21
22
  truncated: boolean;
22
23
  originalBytes: number;
23
24
  limitBytes: number;
24
25
  }
26
+ export interface ShellDiagnostic {
27
+ kind: "command-not-found" | "path-not-found" | "permission-denied" | "shell-syntax" | "timeout" | "cancelled" | "non-zero-exit";
28
+ message: string;
29
+ hint?: string;
30
+ }
25
31
  export interface ShellResult {
26
32
  exitCode: number | null;
27
33
  signal: NodeJS.Signals | null;
@@ -33,6 +39,7 @@ export interface ShellResult {
33
39
  stderr: TruncationMetadata;
34
40
  };
35
41
  terminationReason: "timeout" | "cancelled" | null;
42
+ diagnostic?: ShellDiagnostic;
36
43
  }
37
44
  export interface ShellBackgroundResult extends ShellResult {
38
45
  jobId: string;
@@ -55,17 +62,15 @@ export declare function normalizeShellCommand(input: {
55
62
  command: string;
56
63
  args: string[];
57
64
  };
58
- type WindowsShellKind = "pwsh" | "powershell" | "cmd";
59
- /**
60
- * Build the command line handed to cmd.exe via `spawn(shell: true)` on Windows.
61
- * `commandLine` is the pre-quoted line used directly for the cmd.exe fallback.
62
- *
63
- * For PowerShell we do not pass the raw line through cmd: `-EncodedCommand`
64
- * (UTF-16LE base64) carries the script untouched, so arguments with spaces,
65
- * quotes or `&` reach the child program exactly as given. `chcp 65001` keeps
66
- * the console code page UTF-8 so redirected pipes decode consistently.
67
- */
68
- export declare function buildWindowsCommandLine(kind: WindowsShellKind, commandLine: string, command: string, args: readonly string[]): string;
65
+ export type RuntimeShell = {
66
+ kind: "pwsh" | "powershell" | "cmd";
67
+ command: string;
68
+ } | {
69
+ kind: "posix";
70
+ command: string;
71
+ };
72
+ /** The shell reported to the model, checked by doctor, and used for fallbacks. */
73
+ export declare function resolveRuntimeShell(platform?: NodeJS.Platform | string, environment?: NodeJS.ProcessEnv): RuntimeShell | undefined;
69
74
  export declare function createShellTool(workspace: string, options?: ShellToolOptions): ShellTool;
70
- export declare function executeShell(root: string, input: z.infer<typeof ShellInput>, cancellation: AbortSignal, maxBytes: number, onOutput?: (stream: "stdout" | "stderr", text: string) => void): Promise<ShellResult>;
75
+ export declare function executeShell(root: string, input: z.infer<typeof ShellInput>, cancellation: AbortSignal, maxBytes: number, environment?: NodeJS.ProcessEnv, onOutput?: (stream: "stdout" | "stderr", text: string) => void): Promise<ShellResult>;
71
76
  export {};
@@ -39,6 +39,7 @@ export interface TerminalToolPresentation {
39
39
  command?: string;
40
40
  stdout?: string;
41
41
  stderr?: string;
42
+ diagnostic?: string;
42
43
  exitCode?: number | null;
43
44
  state?: "running" | "completed" | "failed" | "cancelled";
44
45
  truncated?: boolean;
@@ -76,7 +77,7 @@ export interface JobToolPresentation {
76
77
  }
77
78
  export type ToolPresentation = ChangeSetPresentation | FileChangePresentation | GenericToolPresentation | TerminalToolPresentation | WebToolPresentation | JobToolPresentation;
78
79
  export declare function withToolPresentation<T extends object>(output: T, presentation: ToolPresentation): T;
79
- export declare function getToolPresentation(output: unknown): FileChangePresentation | undefined;
80
+ export declare function getToolPresentation(output: unknown): ToolPresentation | undefined;
80
81
  export interface ToolDefinition<T, O = unknown> {
81
82
  name: string;
82
83
  description: string;
@@ -1,4 +1,4 @@
1
- export declare const MVP_COMMANDS: readonly ["model", "init", "config", "login", "logout", "permissions", "skills", "plugins", "hooks", "tasks", "finish", "compact", "clear", "help", "exit", "audit", "usage", "loop", "goal", "evolve", "mcp", "commit", "review", "explain", "ide", "memory", "remember", "forget", "forget-cold", "checkpoint", "tree", "rewind", "unrevert", "fork", "pals", "chat", "co-work", "tool"];
1
+ export declare const MVP_COMMANDS: readonly ["model", "init", "config", "login", "logout", "permissions", "skills", "plugins", "hooks", "tasks", "finish", "compact", "clear", "help", "exit", "audit", "usage", "doctor", "loop", "goal", "evolve", "mcp", "commit", "review", "explain", "ide", "memory", "remember", "forget", "forget-cold", "checkpoint", "tree", "rewind", "unrevert", "fork", "pals", "chat", "co-work", "tool"];
2
2
  export declare const COMMAND_DESCRIPTIONS: Record<(typeof MVP_COMMANDS)[number], string>;
3
3
  export type PermissionCommandMode = PermissionMode;
4
4
  export type ModelRole = "main" | "subagent";
@@ -4,6 +4,7 @@ import type { PermissionMode } from "../permissions/engine.js";
4
4
  import type { SkillMetadata } from "../skills/registry.js";
5
5
  import { type McpSlashCommand, type ModelRole } from "./commands.js";
6
6
  import type { QuestionBridge } from "../tools/ask-user-question.js";
7
+ import type { MemoryRestartContinuation } from "../utils/memory-restart.js";
7
8
  import type { MemoryType } from "../memory/types.js";
8
9
  import { type AgentQueueSnapshot } from "../agent/message-queue.js";
9
10
  import type { SessionTreeNode } from "../session/tree.js";
@@ -113,6 +114,14 @@ export interface SessionServices {
113
114
  runSkill(skill: string, prompt: string, signal: AbortSignal): AsyncIterable<AgentEvent>;
114
115
  runLoop(goal: string, signal: AbortSignal): AsyncIterable<AgentEvent>;
115
116
  runGoal(goal: string, signal: AbortSignal): AsyncIterable<AgentEvent>;
117
+ /** Resume a /loop interrupted by a heap rotation, keyed by its persisted id. */
118
+ resumeLoop?(loopId: string, signal: AbortSignal): AsyncIterable<AgentEvent>;
119
+ /** Resume a /goal interrupted by a heap rotation, keyed by its persisted id. */
120
+ resumeGoal?(goalId: string, signal: AbortSignal): AsyncIterable<AgentEvent>;
121
+ /** The loop/goal a relaunched process should resume after a rotation, consumed once. */
122
+ continuation?(): MemoryRestartContinuation | undefined;
123
+ /** True after the runtime has committed to replacing the current heap. */
124
+ rotationPending?(): boolean;
116
125
  mcp(command: McpSlashCommand, signal: AbortSignal): Promise<string>;
117
126
  ide?(): Promise<string>;
118
127
  ideContext?(): Promise<IdeEditorContext | undefined>;
@@ -130,6 +139,7 @@ export interface SessionServices {
130
139
  hooksStatus(): readonly unknown[];
131
140
  tasks(): unknown;
132
141
  audit(toolFilter?: string): string | Promise<string>;
142
+ doctor?(): string | Promise<string>;
133
143
  evolve(args: readonly string[]): string | Promise<string>;
134
144
  gitCommit?(hint: string | undefined, signal: AbortSignal): Promise<string>;
135
145
  gitReview?(focus: string | undefined, signal: AbortSignal): Promise<string>;
@@ -185,6 +195,8 @@ export declare class FlavorSession {
185
195
  constructor(services: SessionServices);
186
196
  get active(): boolean;
187
197
  queueSnapshot(): AgentQueueSnapshot;
198
+ /** True when start() admitted a persisted /loop or /goal continuation. */
199
+ get rotationContinuationResumed(): boolean;
188
200
  clearQueue(): AgentQueueSnapshot;
189
201
  whenIdle(): Promise<void>;
190
202
  steer(input: string): void;
@@ -77,6 +77,9 @@ export interface TranscriptState {
77
77
  */
78
78
  export declare const MAX_TRANSCRIPT_TURNS = 200;
79
79
  export declare const MAX_TRANSCRIPT_CHARS = 2000000;
80
+ /** A /loop or /goal is one presentation turn and can run for days. */
81
+ export declare const MAX_ACTIVE_TRANSCRIPT_BLOCKS = 160;
82
+ export declare const MAX_ACTIVE_ASSISTANT_CHARS = 64000;
80
83
  export type TranscriptAction = {
81
84
  type: "hydrate";
82
85
  messages: readonly TranscriptHistoryMessage[];
@@ -102,3 +105,9 @@ export declare function createTranscriptState(): TranscriptState;
102
105
  export declare function transcriptReducer(state: TranscriptState, action: TranscriptAction): TranscriptState;
103
106
  export declare function transcriptFromLegacyConversation(messages: readonly TranscriptHistoryMessage[], compact?: TranscriptCompactBoundary): TranscriptState;
104
107
  export declare function restoreTranscriptState(state: TranscriptState): TranscriptState;
108
+ /** Rotation-only diagnostic; callers invoke it at most once per restart. */
109
+ export declare function transcriptCensus(state: TranscriptState): {
110
+ turns: number;
111
+ blocks: number;
112
+ chars: number;
113
+ };
@@ -0,0 +1,20 @@
1
+ export declare const NPM_PACKAGE_NAME = "flavor-code";
2
+ interface RegistryResponse {
3
+ ok: boolean;
4
+ json(): Promise<unknown>;
5
+ }
6
+ export type RegistryFetch = (url: string, init?: {
7
+ signal?: AbortSignal;
8
+ }) => Promise<RegistryResponse>;
9
+ export interface UpdateCheckOptions {
10
+ /** Injectable fetch for tests; defaults to the global Node fetch. */
11
+ fetchImpl?: RegistryFetch;
12
+ timeoutMs?: number;
13
+ }
14
+ /** Returns `latest` only when it is a valid semver strictly newer than `current`. */
15
+ export declare function findNewerVersion(current: string, latest: string): string | undefined;
16
+ /** Fetch the latest published version from the npm registry; undefined on any failure. */
17
+ export declare function fetchLatestVersion(options?: UpdateCheckOptions): Promise<string | undefined>;
18
+ /** Resolves the newer version to upgrade to, or undefined when up to date / unreachable. */
19
+ export declare function checkForUpdate(current: string, options?: UpdateCheckOptions): Promise<string | undefined>;
20
+ export {};
@@ -0,0 +1,20 @@
1
+ /** Wait without retaining an abort listener after the operation settles.
2
+ * The operation must still receive the signal when it supports cancellation.
3
+ */
4
+ export declare function waitWithSignal<T>(operation: Promise<T>, signal?: AbortSignal): Promise<T>;
5
+ export interface ScopedAbortSignal {
6
+ readonly signal: AbortSignal;
7
+ dispose(): void;
8
+ }
9
+ /**
10
+ * Give one provider request its own short-lived signal while preserving
11
+ * cancellation from the enclosing turn.
12
+ *
13
+ * Some HTTP SDKs attach a once-only listener to the caller's signal and do
14
+ * not remove it after a successful request. Reusing a turn signal for
15
+ * hundreds of agent iterations then retains every request controller until
16
+ * the entire turn ends. Disposing this scope unlinks the turn and aborts the
17
+ * derived signal so SDK listeners and any unfinished response body release
18
+ * their references immediately.
19
+ */
20
+ export declare function createScopedAbortSignal(parent?: AbortSignal): ScopedAbortSignal;
@@ -4,6 +4,7 @@ export interface ExecFileNoThrowOptions {
4
4
  env?: NodeJS.ProcessEnv;
5
5
  stdin?: "ignore" | "inherit" | "pipe";
6
6
  input?: string;
7
+ signal?: AbortSignal;
7
8
  }
8
9
  export declare function execFileNoThrow(file: string, args: string[], options?: ExecFileNoThrowOptions): Promise<{
9
10
  stdout: string;
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Heap watermarks for the controlled rotation protocol.
3
+ *
4
+ * Long-running sessions (interactive turns, /loop cycles, /goal rounds) rotate
5
+ * onto a fresh heap instead of growing until V8 dies. Two watermarks:
6
+ *
7
+ * - MEMORY_PRESSURE_HEAP_RATIO: hard guard checked before every model call.
8
+ * Tripping it stops the current turn; the session is persisted first.
9
+ * - MEMORY_ROTATION_HEAP_RATIO: soft guard checked only at turn/cycle/round
10
+ * boundaries. Tripping it rotates between units of work, so multi-day runs
11
+ * keep going on a fresh heap without losing the loop or goal in flight.
12
+ *
13
+ * Both readings are GC-verified when --expose-gc is available (the launcher
14
+ * injects it): heapUsed includes uncollected garbage, and declaring pressure
15
+ * on garbage alone would rotate or stop turns for no reason. A full GC before
16
+ * judging keeps the decision about the live set only.
17
+ */
18
+ export declare const MEMORY_PRESSURE_HEAP_RATIO = 0.8;
19
+ export declare const MEMORY_ROTATION_HEAP_RATIO = 0.6;
20
+ export declare const MEMORY_PRESSURE_RSS_RATIO = 0.75;
21
+ export declare const MEMORY_ROTATION_RSS_RATIO = 0.6;
22
+ export interface HeapReading {
23
+ heapUsed: number;
24
+ heapLimit: number;
25
+ ratio: number;
26
+ /** Ratio measured after a forced full GC; undefined when gc is not exposed. */
27
+ verifiedRatio?: number;
28
+ gcVerified: boolean;
29
+ rss?: number;
30
+ memoryLimit?: number;
31
+ rssRatio?: number;
32
+ external?: number;
33
+ arrayBuffers?: number;
34
+ }
35
+ export declare function readHeap(): {
36
+ heapUsed: number;
37
+ heapLimit: number;
38
+ ratio: number;
39
+ };
40
+ /**
41
+ * Hard-guard reading. Returns undefined below the threshold; when the raw
42
+ * reading crosses it, a full GC (if exposed) decides whether the live set
43
+ * really is that large. Without --expose-gc the raw reading stands.
44
+ */
45
+ export declare function verifiedHeapPressure(threshold: number): HeapReading | undefined;
46
+ /**
47
+ * Boundary rotation decision. Cheap below the precheck ratio; above it the
48
+ * live set is measured with a full GC and compared against the soft
49
+ * watermark. Without --expose-gc only a raw reading at the hard watermark
50
+ * rotates, so an uninstrumented process degrades to the old behaviour.
51
+ */
52
+ export declare function heapRotationNeeded(): HeapReading | undefined;
53
+ /**
54
+ * Explicit opt-in only. The launcher already asks V8 for one near-limit
55
+ * snapshot; synchronously taking another in the recovery path can exhaust the
56
+ * very heap/RSS headroom needed to persist and exit cleanly.
57
+ */
58
+ export declare function heapSnapshotWarranted(_reading: HeapReading): boolean;
@@ -7,23 +7,62 @@
7
7
  * relaunches the CLI with `--resume <sessionId>`, so memory pressure restores
8
8
  * the saved session instead of ending in a fatal V8 OOM crash. The interrupted
9
9
  * turn is intentionally not replayed because it may contain non-idempotent tools.
10
+ *
11
+ * Boundary rotations (between turns, /loop cycles, /goal rounds) carry a
12
+ * `continuation` in the marker: the relaunched process picks the interrupted
13
+ * loop or goal back up from its persisted state, so multi-day autonomous runs
14
+ * survive heap rotation without losing the long-running task.
10
15
  */
11
16
  export declare const MEMORY_RESTART_EXIT_CODE = 75;
12
17
  export declare const MEMORY_RESTART_MARKER_FILE = "memory-restart.json";
13
- export declare const MEMORY_RESTART_MAX_ATTEMPTS = 3;
18
+ /**
19
+ * Rotations are seamless (the session and any loop/goal resume automatically),
20
+ * so the budget only exists to stop a pathological spin: 24 rotations inside
21
+ * one hour still covers a multi-day run rotating every few hours.
22
+ */
23
+ export declare const MEMORY_RESTART_MAX_ATTEMPTS = 24;
14
24
  export declare const MEMORY_RESTART_WINDOW_MS: number;
25
+ /** Two rotations closer together than this mean the fresh heap is born heavy; stop rotating and let the hard guard decide. */
26
+ export declare const MEMORY_RESTART_MIN_GAP_MS: number;
27
+ /**
28
+ * Leave enough time for a slow launcher, host reboot, or unattended machine
29
+ * wake-up to recover a persisted long task. Session/id validation still keeps
30
+ * an unrelated stale marker from resuming in the wrong process.
31
+ */
32
+ export declare const MEMORY_RESTART_CONTINUATION_TTL_MS: number;
33
+ export interface MemoryRestartContinuation {
34
+ kind: "loop" | "goal";
35
+ id: string;
36
+ }
15
37
  export interface MemoryRestartMarker {
16
38
  sessionId: string;
39
+ /** Start of the fixed accounting window; unlike requestedAt this does not slide. */
40
+ windowStartedAt?: string;
17
41
  requestedAt: string;
18
42
  attempts: number;
43
+ continuation?: MemoryRestartContinuation;
19
44
  }
45
+ /** Recorded when a rotation is requested; orchestrators skip terminal bookkeeping on the way out. */
46
+ export declare function markMemoryRotation(): void;
47
+ export declare function memoryRotationActive(): boolean;
48
+ /** In-process hosts clear this only after the old runtime has been fully disposed. */
49
+ export declare function clearMemoryRotation(): void;
20
50
  export declare function memoryRestartMarkerPath(workspace: string): string;
21
51
  /**
22
- * Count restarts per session inside a rolling window. A marker for a
52
+ * Count restarts per session inside a fixed window. A marker for a
23
53
  * different session or an expired window starts counting from one again, so
24
54
  * a healthy long-lived session never exhausts the budget.
25
55
  */
26
- export declare function nextMemoryRestartMarker(previous: MemoryRestartMarker | undefined, sessionId: string, now: Date): MemoryRestartMarker;
56
+ export declare function nextMemoryRestartMarker(previous: MemoryRestartMarker | undefined, sessionId: string, now: Date, continuation?: MemoryRestartContinuation): MemoryRestartMarker;
57
+ /**
58
+ * Remove a consumed continuation without turning marker consumption into a
59
+ * second restart attempt or extending the accounting/cooldown windows.
60
+ */
61
+ export declare function consumedMemoryRestartMarker(marker: MemoryRestartMarker): MemoryRestartMarker;
62
+ /** True when the previous rotation for this session is too recent for another seamless one. */
63
+ export declare function rotationCooldownActive(marker: MemoryRestartMarker | undefined, sessionId: string, now: Date): boolean;
64
+ /** The continuation a relaunched process should pick up, if still fresh. */
65
+ export declare function pendingContinuation(marker: MemoryRestartMarker | undefined, sessionId: string, now: Date): MemoryRestartContinuation | undefined;
27
66
  export declare function shouldRelaunchForMemoryRestart(marker: MemoryRestartMarker | undefined): boolean;
28
67
  /**
29
68
  * Rebuild the CLI arguments for the relaunched process: drop any existing
@@ -0,0 +1,2 @@
1
+ /** POSIX callers must spawn the root in its own process group (detached=true). */
2
+ export declare function terminateProcessTree(pid: number | undefined): Promise<void>;
@@ -0,0 +1,36 @@
1
+ import type { HeapReading } from "./heap.js";
2
+ /**
3
+ * Rotation forensics. Every heap rotation leaves a retention census: each
4
+ * major in-memory holder reports its retained size, so the next recurrence
5
+ * names its own grower instead of restarting with zero evidence. A full
6
+ * .heapsnapshot accompanies rotations whose verified live set is near the
7
+ * hard limit (or every rotation under FLAVOR_HEAP_SNAPSHOT_ON_ROTATE=1).
8
+ */
9
+ export interface RotationCensusHolder {
10
+ entries?: number;
11
+ chars?: number;
12
+ bytes?: number;
13
+ }
14
+ export interface RotationCensus {
15
+ at: string;
16
+ reason: string;
17
+ sessionId: string;
18
+ heap: {
19
+ heapUsedMb: number;
20
+ heapLimitMb: number;
21
+ rawRatio: number;
22
+ verifiedRatio?: number;
23
+ gcVerified: boolean;
24
+ rssMb: number;
25
+ externalMb: number;
26
+ arrayBuffersMb: number;
27
+ memoryLimitMb?: number;
28
+ rssRatio?: number;
29
+ };
30
+ holders: Record<string, RotationCensusHolder>;
31
+ }
32
+ export declare function censusHeapBlock(reading: HeapReading): RotationCensus["heap"];
33
+ /** Best-effort: a failed census must never block the rotation itself. */
34
+ export declare function writeRotationCensus(workspace: string, census: RotationCensus): string | undefined;
35
+ /** Best-effort heap snapshot; synchronous and slow on large heaps by nature. */
36
+ export declare function writeRotationHeapSnapshot(workspace: string): string | undefined;
@@ -0,0 +1,3 @@
1
+ export declare function gte(a: string, b: string): boolean;
2
+ export declare function gt(a: string, b: string): boolean;
3
+ export declare function isValidVersion(value: string): boolean;
@@ -14,3 +14,5 @@ export interface PrepareSpawnOptions {
14
14
  * the original argv boundary and all other platforms are unchanged.
15
15
  */
16
16
  export declare function prepareSpawnInvocation(command: string, args: readonly string[], options?: PrepareSpawnOptions): PreparedSpawnInvocation;
17
+ /** Resolve an executable exactly as the structured Shell runner will see it. */
18
+ export declare function resolveExecutablePath(command: string, options?: PrepareSpawnOptions): string | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flavor-code",
3
- "version": "1.3.23",
3
+ "version": "1.4.0-beta.10",
4
4
  "author": "YachuanWzh",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -31,7 +31,7 @@
31
31
  "scripts": {
32
32
  "build": "npm run build:icons && npm run build:cli && npm run build:desktop",
33
33
  "build:icons": "node scripts/build-icons.mjs",
34
- "build:cli": "tsup && tsc -p tsconfig.sdk.json && node -e \"require('fs').cpSync('src/init/astgraph','dist/astgraph',{recursive:true})\"",
34
+ "build:cli": "tsup && tsc -p tsconfig.sdk.json && node scripts/assert-production-cli.mjs",
35
35
  "build:desktop": "npm run build:desktop:main && npm run build:desktop:renderer",
36
36
  "build:desktop:main": "tsup --config tsup.desktop.config.ts",
37
37
  "build:desktop:renderer": "vite build --config vite.desktop.config.ts",
@@ -52,6 +52,7 @@
52
52
  "smoke:install": "node scripts/smoke-install.mjs",
53
53
  "smoke:d2c-worker": "npm run build:desktop:main && node scripts/smoke-d2c-worker.mjs",
54
54
  "stress:context": "vitest run scripts/stress-context-memory.test.ts --reporter=verbose",
55
+ "stress:tui-memory": "npm run build:cli && node scripts/run-tui-memory-stress.mjs",
55
56
  "stress:production-memory": "npm run build:cli && node scripts/stress-production-memory.mjs",
56
57
  "evidence:crash-fix": "vitest run scripts/evidence-crash-replay.test.ts --reporter=verbose",
57
58
  "prepack": "npm run build"