scream-code 0.13.5 → 0.13.7

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.
@@ -6,7 +6,7 @@ const __dirname = __cjsShimDirname(__filename);
6
6
  import { i as __require, o as __toESM, r as __exportAll, t as __commonJSMin } from "./chunk-D90kvbyJ.mjs";
7
7
  import { C as join$1, D as resolve$1, E as relative$1, S as isAbsolute$1, T as parse$7, a as isSupportedFile, b as basename$1, i as ingestFile, r as ingestDirectory, t as multiSearch, w as normalize, x as dirname$2, y as KnowledgeStore } from "./src-BH9W5k24.mjs";
8
8
  import { t as require_base64_js } from "./base64-js-DzVmk6Nb.mjs";
9
- import { a as setLocale, i as getLocale, n as assertScreamHostIdentity, o as t, r as createScreamDefaultHeaders, t as TextInputDialogComponent } from "./text-input-dialog-ClcJf9pu.mjs";
9
+ import { a as setLocale, i as getLocale, n as assertScreamHostIdentity, o as t, r as createScreamDefaultHeaders, t as TextInputDialogComponent } from "./text-input-dialog-DstXBOl9.mjs";
10
10
  import { createRequire } from "node:module";
11
11
  import { createHash, randomBytes, randomInt, randomUUID } from "node:crypto";
12
12
  import * as fs$1 from "node:fs/promises";
@@ -9270,7 +9270,8 @@ var AnthropicChatProvider = class {
9270
9270
  return new Anthropic({
9271
9271
  apiKey,
9272
9272
  baseURL: this._baseUrl,
9273
- defaultHeaders: this._defaultHeaders
9273
+ defaultHeaders: this._defaultHeaders,
9274
+ maxRetries: 0
9274
9275
  });
9275
9276
  }
9276
9277
  withThinking(effort) {
@@ -44625,7 +44626,8 @@ var ScreamFiles = class {
44625
44626
  this._client = options.apiKey === void 0 || options.apiKey.length === 0 ? void 0 : new OpenAI({
44626
44627
  apiKey: options.apiKey,
44627
44628
  baseURL: options.baseUrl,
44628
- defaultHeaders: options.defaultHeaders
44629
+ defaultHeaders: options.defaultHeaders,
44630
+ maxRetries: 0
44629
44631
  });
44630
44632
  }
44631
44633
  /**
@@ -44684,7 +44686,8 @@ var ScreamFiles = class {
44684
44686
  return new OpenAI({
44685
44687
  apiKey: requireProviderApiKey("ScreamFiles.uploadVideo", a, this._apiKey),
44686
44688
  baseURL: this._baseUrl,
44687
- defaultHeaders
44689
+ defaultHeaders,
44690
+ maxRetries: 0
44688
44691
  });
44689
44692
  });
44690
44693
  }
@@ -44953,7 +44956,8 @@ var ScreamChatProvider = class {
44953
44956
  this._client = this._apiKey === void 0 ? void 0 : new OpenAI({
44954
44957
  apiKey: this._apiKey,
44955
44958
  baseURL: this._baseUrl,
44956
- defaultHeaders: this._defaultHeaders
44959
+ defaultHeaders: this._defaultHeaders,
44960
+ maxRetries: 0
44957
44961
  });
44958
44962
  }
44959
44963
  get modelName() {
@@ -45069,7 +45073,8 @@ var ScreamChatProvider = class {
45069
45073
  return new OpenAI({
45070
45074
  apiKey: requireProviderApiKey("ScreamChatProvider", a, this._apiKey),
45071
45075
  baseURL: this._baseUrl,
45072
- defaultHeaders
45076
+ defaultHeaders,
45077
+ maxRetries: 0
45073
45078
  });
45074
45079
  });
45075
45080
  }
@@ -45338,7 +45343,8 @@ var OpenAILegacyChatProvider = class {
45338
45343
  _buildClient(apiKey, auth) {
45339
45344
  const clientOpts = {
45340
45345
  apiKey,
45341
- baseURL: this._baseUrl
45346
+ baseURL: this._baseUrl,
45347
+ maxRetries: 0
45342
45348
  };
45343
45349
  const defaultHeaders = mergeRequestHeaders(this._defaultHeaders, auth?.headers);
45344
45350
  if (defaultHeaders !== void 0) clientOpts["defaultHeaders"] = defaultHeaders;
@@ -45985,7 +45991,8 @@ var OpenAIResponsesChatProvider = class {
45985
45991
  _buildClient(apiKey, auth) {
45986
45992
  const clientOpts = {
45987
45993
  apiKey,
45988
- baseURL: this._baseUrl
45994
+ baseURL: this._baseUrl,
45995
+ maxRetries: 0
45989
45996
  };
45990
45997
  const defaultHeaders = mergeRequestHeaders(this._defaultHeaders, auth?.headers);
45991
45998
  if (defaultHeaders !== void 0) clientOpts["defaultHeaders"] = defaultHeaders;
@@ -47326,6 +47333,236 @@ function resolveGlobalLogPath(homeDir) {
47326
47333
  return join$1(homeDir, "logs", "scream-code.log");
47327
47334
  }
47328
47335
  //#endregion
47336
+ //#region ../../node_modules/.pnpm/@antfu+utils@9.3.0/node_modules/@antfu/utils/dist/index.mjs
47337
+ function uniq(array) {
47338
+ return Array.from(new Set(array));
47339
+ }
47340
+ function notNullish(v) {
47341
+ return v != null;
47342
+ }
47343
+ function objectMap(obj, fn) {
47344
+ return Object.fromEntries(Object.entries(obj).map(([k, v]) => fn(k, v)).filter(notNullish));
47345
+ }
47346
+ function sleep$1(ms, callback) {
47347
+ return new Promise((resolve) => setTimeout(async () => {
47348
+ await callback?.();
47349
+ resolve();
47350
+ }, ms));
47351
+ }
47352
+ function createControlledPromise() {
47353
+ let resolve, reject;
47354
+ const promise = new Promise((_resolve, _reject) => {
47355
+ resolve = _resolve;
47356
+ reject = _reject;
47357
+ });
47358
+ promise.resolve = resolve;
47359
+ promise.reject = reject;
47360
+ return promise;
47361
+ }
47362
+ //#endregion
47363
+ //#region ../../packages/agent-core/src/utils/abort.ts
47364
+ function abortError() {
47365
+ const error = /* @__PURE__ */ new Error("Aborted");
47366
+ error.name = "AbortError";
47367
+ return error;
47368
+ }
47369
+ /**
47370
+ * Marks an abort the user triggered deliberately (e.g. pressing ESC to
47371
+ * interrupt the agent), as distinct from a timeout, an internal error, or any
47372
+ * other programmatic abort. It travels as the AbortSignal's `reason`, so code
47373
+ * that settles an interrupted operation can tell a user interruption apart from
47374
+ * a failure and report it to the model accordingly instead of emitting a
47375
+ * neutral "was aborted" that the model mistakes for a system problem.
47376
+ *
47377
+ * `name` stays 'AbortError' so existing `isAbortError()` checks (and
47378
+ * `AbortSignal.throwIfAborted()`) keep treating it as an abort.
47379
+ */
47380
+ var UserCancellationError = class extends Error {
47381
+ userCancelled = true;
47382
+ constructor() {
47383
+ super("Aborted by the user");
47384
+ this.name = "AbortError";
47385
+ }
47386
+ };
47387
+ function userCancellationReason() {
47388
+ return new UserCancellationError();
47389
+ }
47390
+ function isUserCancellation(value) {
47391
+ return value instanceof UserCancellationError;
47392
+ }
47393
+ function abortable(promise, signal) {
47394
+ signal.throwIfAborted();
47395
+ return new Promise((resolve, reject) => {
47396
+ const onAbort = () => {
47397
+ reject(abortError());
47398
+ };
47399
+ signal.addEventListener("abort", onAbort, { once: true });
47400
+ promise.then(resolve, reject).finally(() => {
47401
+ signal.removeEventListener("abort", onAbort);
47402
+ });
47403
+ });
47404
+ }
47405
+ function linkAbortSignal(source, target) {
47406
+ const onAbort = () => {
47407
+ target.abort(source.reason);
47408
+ };
47409
+ if (source.aborted) {
47410
+ onAbort();
47411
+ return () => {};
47412
+ }
47413
+ source.addEventListener("abort", onAbort, { once: true });
47414
+ return () => {
47415
+ source.removeEventListener("abort", onAbort);
47416
+ };
47417
+ }
47418
+ function createDeadlineAbortSignal(source, timeoutMs) {
47419
+ const controller = new AbortController();
47420
+ const unlinkAbortSignal = linkAbortSignal(source, controller);
47421
+ let didTimeout = false;
47422
+ let timeout = setTimeout(() => {
47423
+ didTimeout = true;
47424
+ controller.abort(abortError());
47425
+ }, timeoutMs);
47426
+ return {
47427
+ signal: controller.signal,
47428
+ timedOut: () => didTimeout,
47429
+ clear: () => {
47430
+ if (timeout !== void 0) clearTimeout(timeout);
47431
+ timeout = void 0;
47432
+ unlinkAbortSignal();
47433
+ }
47434
+ };
47435
+ }
47436
+ //#endregion
47437
+ //#region ../../packages/agent-core/src/loop/errors.ts
47438
+ /**
47439
+ * Loop-local error helpers.
47440
+ */
47441
+ function createMaxStepsExceededError(maxSteps, message) {
47442
+ return new ScreamError(ErrorCodes.LOOP_MAX_STEPS_EXCEEDED, message ?? `Turn exceeded maxSteps=${maxSteps}`, { details: { maxSteps } });
47443
+ }
47444
+ function isMaxStepsExceededError(error) {
47445
+ return isScreamError(error) && error.code === ErrorCodes.LOOP_MAX_STEPS_EXCEEDED;
47446
+ }
47447
+ function isAbortError$1(err) {
47448
+ if (err instanceof Error) return err.name === "AbortError";
47449
+ return false;
47450
+ }
47451
+ function errorMessage$4(err) {
47452
+ if (err instanceof Error) return err.message;
47453
+ return String(err);
47454
+ }
47455
+ const BASE_DELAY_MS = 500;
47456
+ const MAX_DELAY_MS = 32e3;
47457
+ const RETRY_FACTOR = 2;
47458
+ const JITTER_FACTOR = .25;
47459
+ async function chatWithRetry(input) {
47460
+ const maxAttempts = input.maxAttempts ?? 10;
47461
+ if (input.llm.isRetryableError === void 0 || maxAttempts <= 1) {
47462
+ const effectiveMaxAttempts = Math.max(maxAttempts, 1);
47463
+ try {
47464
+ return await input.llm.chat(paramsForAttempt(input, 1, effectiveMaxAttempts));
47465
+ } catch (error) {
47466
+ logRequestFailure(input, error, 1, effectiveMaxAttempts);
47467
+ throw error;
47468
+ }
47469
+ }
47470
+ const delays = retryBackoffDelays(maxAttempts);
47471
+ for (let attempt = 1;; attempt += 1) try {
47472
+ return await input.llm.chat(paramsForAttempt(input, attempt, maxAttempts));
47473
+ } catch (error) {
47474
+ if (error instanceof APIContextOverflowError) {
47475
+ logRequestFailure(input, error, attempt, maxAttempts);
47476
+ throw error;
47477
+ }
47478
+ if (error instanceof APIProviderRateLimitError && error.reason === "QUOTA_EXHAUSTED") {
47479
+ logRequestFailure(input, error, attempt, maxAttempts);
47480
+ throw error;
47481
+ }
47482
+ if (attempt >= maxAttempts || !input.llm.isRetryableError(error)) {
47483
+ logRequestFailure(input, error, attempt, maxAttempts);
47484
+ throw error;
47485
+ }
47486
+ const delayMs = computeDelayMs(error, delays, attempt);
47487
+ input.params.signal.throwIfAborted();
47488
+ input.dispatchEvent({
47489
+ type: "step.retrying",
47490
+ turnId: input.turnId,
47491
+ step: input.currentStep,
47492
+ stepUuid: input.stepUuid,
47493
+ failedAttempt: attempt,
47494
+ nextAttempt: attempt + 1,
47495
+ maxAttempts,
47496
+ delayMs,
47497
+ ...retryErrorFields(error)
47498
+ });
47499
+ await sleepForRetry(delayMs, input.params.signal);
47500
+ }
47501
+ }
47502
+ function computeDelayMs(error, delays, attempt) {
47503
+ const retryAfter = readRetryAfterMs(error);
47504
+ if (retryAfter !== null) return retryAfter;
47505
+ if (error instanceof APIProviderRateLimitError) return calculateRateLimitBackoffMs(error.reason);
47506
+ return delays[attempt - 1] ?? 0;
47507
+ }
47508
+ /**
47509
+ * Server-requested backoff carried on an `APIStatusError` (parsed from
47510
+ * the `Retry-After` response header). When present and positive it
47511
+ * overrides the computed backoff - a server `Retry-After` directive
47512
+ * takes precedence over the local exponential delay.
47513
+ */
47514
+ function readRetryAfterMs(error) {
47515
+ if (typeof error !== "object" || error === null) return null;
47516
+ const value = error.retryAfterMs;
47517
+ return typeof value === "number" && value > 0 ? value : null;
47518
+ }
47519
+ function logRequestFailure(input, error, attempt, maxAttempts) {
47520
+ if (isAbortError$1(error) || input.params.signal.aborted) return;
47521
+ input.log?.warn("llm request failed", {
47522
+ turnStep: `${input.turnId}.${String(input.currentStep)}`,
47523
+ attempt: `${String(attempt)}/${String(maxAttempts)}`,
47524
+ model: input.llm.modelName,
47525
+ ...retryErrorFields(error)
47526
+ });
47527
+ }
47528
+ function paramsForAttempt(input, attempt, maxAttempts) {
47529
+ return {
47530
+ ...input.params,
47531
+ requestLogContext: {
47532
+ turnId: input.turnId,
47533
+ step: input.currentStep,
47534
+ stepUuid: input.stepUuid,
47535
+ attempt,
47536
+ maxAttempts
47537
+ }
47538
+ };
47539
+ }
47540
+ function retryBackoffDelays(maxAttempts) {
47541
+ const count = Math.max(maxAttempts - 1, 0);
47542
+ const delays = [];
47543
+ for (let i = 0; i < count; i += 1) {
47544
+ const base = Math.min(BASE_DELAY_MS * Math.pow(RETRY_FACTOR, i), MAX_DELAY_MS);
47545
+ delays.push(base + Math.random() * JITTER_FACTOR * base);
47546
+ }
47547
+ return delays;
47548
+ }
47549
+ async function sleepForRetry(delayMs, signal) {
47550
+ signal.throwIfAborted();
47551
+ await abortable(sleep$1(delayMs), signal);
47552
+ }
47553
+ function retryErrorFields(error) {
47554
+ return {
47555
+ errorName: error instanceof Error ? error.name : typeof error,
47556
+ errorMessage: error instanceof Error ? error.message : String(error),
47557
+ statusCode: maybeStatusCode(error)
47558
+ };
47559
+ }
47560
+ function maybeStatusCode(error) {
47561
+ if (typeof error !== "object" || error === null) return void 0;
47562
+ const statusCode = error.statusCode;
47563
+ return typeof statusCode === "number" ? statusCode : void 0;
47564
+ }
47565
+ //#endregion
47329
47566
  //#region ../../packages/agent-core/src/utils/tokens.ts
47330
47567
  /**
47331
47568
  * WeakMap cache for per-message token estimates. Messages are immutable once
@@ -47382,25 +47619,6 @@ function estimateTokensForContentPart(part) {
47382
47619
  return 0;
47383
47620
  }
47384
47621
  //#endregion
47385
- //#region ../../packages/agent-core/src/loop/errors.ts
47386
- /**
47387
- * Loop-local error helpers.
47388
- */
47389
- function createMaxStepsExceededError(maxSteps, message) {
47390
- return new ScreamError(ErrorCodes.LOOP_MAX_STEPS_EXCEEDED, message ?? `Turn exceeded maxSteps=${maxSteps}`, { details: { maxSteps } });
47391
- }
47392
- function isMaxStepsExceededError(error) {
47393
- return isScreamError(error) && error.code === ErrorCodes.LOOP_MAX_STEPS_EXCEEDED;
47394
- }
47395
- function isAbortError$1(err) {
47396
- if (err instanceof Error) return err.name === "AbortError";
47397
- return false;
47398
- }
47399
- function errorMessage$4(err) {
47400
- if (err instanceof Error) return err.message;
47401
- return String(err);
47402
- }
47403
- //#endregion
47404
47622
  //#region ../../packages/agent-core/src/utils/per-id-json-store.ts
47405
47623
  /**
47406
47624
  * Per-id JSON record store — write each value as `<rootDir>/<subdir>/<id>.json`.
@@ -51659,80 +51877,6 @@ function normalizePath$1(path) {
51659
51877
  return folded;
51660
51878
  }
51661
51879
  //#endregion
51662
- //#region ../../packages/agent-core/src/utils/abort.ts
51663
- function abortError() {
51664
- const error = /* @__PURE__ */ new Error("Aborted");
51665
- error.name = "AbortError";
51666
- return error;
51667
- }
51668
- /**
51669
- * Marks an abort the user triggered deliberately (e.g. pressing ESC to
51670
- * interrupt the agent), as distinct from a timeout, an internal error, or any
51671
- * other programmatic abort. It travels as the AbortSignal's `reason`, so code
51672
- * that settles an interrupted operation can tell a user interruption apart from
51673
- * a failure and report it to the model accordingly instead of emitting a
51674
- * neutral "was aborted" that the model mistakes for a system problem.
51675
- *
51676
- * `name` stays 'AbortError' so existing `isAbortError()` checks (and
51677
- * `AbortSignal.throwIfAborted()`) keep treating it as an abort.
51678
- */
51679
- var UserCancellationError = class extends Error {
51680
- userCancelled = true;
51681
- constructor() {
51682
- super("Aborted by the user");
51683
- this.name = "AbortError";
51684
- }
51685
- };
51686
- function userCancellationReason() {
51687
- return new UserCancellationError();
51688
- }
51689
- function isUserCancellation(value) {
51690
- return value instanceof UserCancellationError;
51691
- }
51692
- function abortable(promise, signal) {
51693
- signal.throwIfAborted();
51694
- return new Promise((resolve, reject) => {
51695
- const onAbort = () => {
51696
- reject(abortError());
51697
- };
51698
- signal.addEventListener("abort", onAbort, { once: true });
51699
- promise.then(resolve, reject).finally(() => {
51700
- signal.removeEventListener("abort", onAbort);
51701
- });
51702
- });
51703
- }
51704
- function linkAbortSignal(source, target) {
51705
- const onAbort = () => {
51706
- target.abort(source.reason);
51707
- };
51708
- if (source.aborted) {
51709
- onAbort();
51710
- return () => {};
51711
- }
51712
- source.addEventListener("abort", onAbort, { once: true });
51713
- return () => {
51714
- source.removeEventListener("abort", onAbort);
51715
- };
51716
- }
51717
- function createDeadlineAbortSignal(source, timeoutMs) {
51718
- const controller = new AbortController();
51719
- const unlinkAbortSignal = linkAbortSignal(source, controller);
51720
- let didTimeout = false;
51721
- let timeout = setTimeout(() => {
51722
- didTimeout = true;
51723
- controller.abort(abortError());
51724
- }, timeoutMs);
51725
- return {
51726
- signal: controller.signal,
51727
- timedOut: () => didTimeout,
51728
- clear: () => {
51729
- if (timeout !== void 0) clearTimeout(timeout);
51730
- timeout = void 0;
51731
- unlinkAbortSignal();
51732
- }
51733
- };
51734
- }
51735
- //#endregion
51736
51880
  //#region ../../packages/agent-core/src/tools/builtin/collaboration/agent-background-disabled.md
51737
51881
  var agent_background_disabled_default = "Background agent execution is disabled for this agent. Do not set `run_in_background=true`.";
51738
51882
  //#endregion
@@ -54938,7 +55082,7 @@ var LspClient = class {
54938
55082
  while (Date.now() - start < timeoutMs) {
54939
55083
  const collected = this.collectedDiagnostics.get(uri);
54940
55084
  if (collected !== void 0) return collected;
54941
- await sleep$1(100);
55085
+ await sleep(100);
54942
55086
  }
54943
55087
  return this.collectedDiagnostics.get(uri) ?? [];
54944
55088
  }
@@ -55040,7 +55184,7 @@ function uriToPath(uri) {
55040
55184
  if (process.platform === "win32" && filePath.startsWith("/") && /^[A-Za-z]:/.test(filePath.slice(1))) filePath = filePath.slice(1);
55041
55185
  return filePath;
55042
55186
  }
55043
- function sleep$1(ms) {
55187
+ function sleep(ms) {
55044
55188
  return new Promise((resolve) => {
55045
55189
  setTimeout(resolve, ms);
55046
55190
  });
@@ -66339,6 +66483,7 @@ async function parseManifest(pluginRoot) {
66339
66483
  if (await isFile$1(path.join(pluginRoot, "SKILL.md"))) skills = [pluginRoot];
66340
66484
  }
66341
66485
  const skillInstructions = typeof raw["skillInstructions"] === "string" ? raw["skillInstructions"] : void 0;
66486
+ const config = typeof raw["config"] === "object" && raw["config"] !== null && !Array.isArray(raw["config"]) ? raw["config"] : void 0;
66342
66487
  recordUnsupportedRuntimeFields(raw, diagnostics);
66343
66488
  return {
66344
66489
  manifest: {
@@ -66353,7 +66498,8 @@ async function parseManifest(pluginRoot) {
66353
66498
  sessionStart: readSessionStart(raw["sessionStart"], diagnostics),
66354
66499
  mcpServers: await readMcpServers(pluginRoot, raw["mcpServers"], diagnostics),
66355
66500
  interface: readInterface(raw["interface"]),
66356
- skillInstructions
66501
+ skillInstructions,
66502
+ config
66357
66503
  },
66358
66504
  manifestKind,
66359
66505
  manifestPath,
@@ -67466,7 +67612,7 @@ var MakeSkillPlanTool = class {
67466
67612
  }
67467
67613
  async generatePlan(args) {
67468
67614
  const userPrompt = buildUserPrompt(args, buildTranscript(this.agent.context.history));
67469
- const response = await this.agent.generate(this.agent.config.provider, SYSTEM_PROMPT, [], [{
67615
+ const response = await this.agent.generateWithRetry(this.agent.config.provider, SYSTEM_PROMPT, [], [{
67470
67616
  role: "user",
67471
67617
  content: [{
67472
67618
  type: "text",
@@ -76308,143 +76454,6 @@ function buildBackgroundTaskNotificationBody(info, isAgentTask) {
76308
76454
  ].join("\n")}`;
76309
76455
  }
76310
76456
  //#endregion
76311
- //#region ../../node_modules/.pnpm/@antfu+utils@9.3.0/node_modules/@antfu/utils/dist/index.mjs
76312
- function uniq(array) {
76313
- return Array.from(new Set(array));
76314
- }
76315
- function notNullish(v) {
76316
- return v != null;
76317
- }
76318
- function objectMap(obj, fn) {
76319
- return Object.fromEntries(Object.entries(obj).map(([k, v]) => fn(k, v)).filter(notNullish));
76320
- }
76321
- function sleep(ms, callback) {
76322
- return new Promise((resolve) => setTimeout(async () => {
76323
- await callback?.();
76324
- resolve();
76325
- }, ms));
76326
- }
76327
- function createControlledPromise() {
76328
- let resolve, reject;
76329
- const promise = new Promise((_resolve, _reject) => {
76330
- resolve = _resolve;
76331
- reject = _reject;
76332
- });
76333
- promise.resolve = resolve;
76334
- promise.reject = reject;
76335
- return promise;
76336
- }
76337
- const BASE_DELAY_MS = 500;
76338
- const MAX_DELAY_MS = 32e3;
76339
- const RETRY_FACTOR = 2;
76340
- const JITTER_FACTOR = .25;
76341
- async function chatWithRetry(input) {
76342
- const maxAttempts = input.maxAttempts ?? 10;
76343
- if (input.llm.isRetryableError === void 0 || maxAttempts <= 1) {
76344
- const effectiveMaxAttempts = Math.max(maxAttempts, 1);
76345
- try {
76346
- return await input.llm.chat(paramsForAttempt(input, 1, effectiveMaxAttempts));
76347
- } catch (error) {
76348
- logRequestFailure(input, error, 1, effectiveMaxAttempts);
76349
- throw error;
76350
- }
76351
- }
76352
- const delays = retryBackoffDelays(maxAttempts);
76353
- for (let attempt = 1;; attempt += 1) try {
76354
- return await input.llm.chat(paramsForAttempt(input, attempt, maxAttempts));
76355
- } catch (error) {
76356
- if (error instanceof APIContextOverflowError) {
76357
- logRequestFailure(input, error, attempt, maxAttempts);
76358
- throw error;
76359
- }
76360
- if (error instanceof APIProviderRateLimitError && error.reason === "QUOTA_EXHAUSTED") {
76361
- logRequestFailure(input, error, attempt, maxAttempts);
76362
- throw error;
76363
- }
76364
- if (attempt >= maxAttempts || !input.llm.isRetryableError(error)) {
76365
- logRequestFailure(input, error, attempt, maxAttempts);
76366
- throw error;
76367
- }
76368
- const delayMs = computeDelayMs(error, delays, attempt);
76369
- input.params.signal.throwIfAborted();
76370
- input.dispatchEvent({
76371
- type: "step.retrying",
76372
- turnId: input.turnId,
76373
- step: input.currentStep,
76374
- stepUuid: input.stepUuid,
76375
- failedAttempt: attempt,
76376
- nextAttempt: attempt + 1,
76377
- maxAttempts,
76378
- delayMs,
76379
- ...retryErrorFields(error)
76380
- });
76381
- await sleepForRetry(delayMs, input.params.signal);
76382
- }
76383
- }
76384
- function computeDelayMs(error, delays, attempt) {
76385
- const retryAfter = readRetryAfterMs(error);
76386
- if (retryAfter !== null) return retryAfter;
76387
- if (error instanceof APIProviderRateLimitError) return calculateRateLimitBackoffMs(error.reason);
76388
- return delays[attempt - 1] ?? 0;
76389
- }
76390
- /**
76391
- * Server-requested backoff carried on an `APIStatusError` (parsed from
76392
- * the `Retry-After` response header). When present and positive it
76393
- * overrides the computed backoff - a server `Retry-After` directive
76394
- * takes precedence over the local exponential delay.
76395
- */
76396
- function readRetryAfterMs(error) {
76397
- if (typeof error !== "object" || error === null) return null;
76398
- const value = error.retryAfterMs;
76399
- return typeof value === "number" && value > 0 ? value : null;
76400
- }
76401
- function logRequestFailure(input, error, attempt, maxAttempts) {
76402
- if (isAbortError$1(error) || input.params.signal.aborted) return;
76403
- input.log?.warn("llm request failed", {
76404
- turnStep: `${input.turnId}.${String(input.currentStep)}`,
76405
- attempt: `${String(attempt)}/${String(maxAttempts)}`,
76406
- model: input.llm.modelName,
76407
- ...retryErrorFields(error)
76408
- });
76409
- }
76410
- function paramsForAttempt(input, attempt, maxAttempts) {
76411
- return {
76412
- ...input.params,
76413
- requestLogContext: {
76414
- turnId: input.turnId,
76415
- step: input.currentStep,
76416
- stepUuid: input.stepUuid,
76417
- attempt,
76418
- maxAttempts
76419
- }
76420
- };
76421
- }
76422
- function retryBackoffDelays(maxAttempts) {
76423
- const count = Math.max(maxAttempts - 1, 0);
76424
- const delays = [];
76425
- for (let i = 0; i < count; i += 1) {
76426
- const base = Math.min(BASE_DELAY_MS * Math.pow(RETRY_FACTOR, i), MAX_DELAY_MS);
76427
- delays.push(base + Math.random() * JITTER_FACTOR * base);
76428
- }
76429
- return delays;
76430
- }
76431
- async function sleepForRetry(delayMs, signal) {
76432
- signal.throwIfAborted();
76433
- await abortable(sleep(delayMs), signal);
76434
- }
76435
- function retryErrorFields(error) {
76436
- return {
76437
- errorName: error instanceof Error ? error.name : typeof error,
76438
- errorMessage: error instanceof Error ? error.message : String(error),
76439
- statusCode: maybeStatusCode(error)
76440
- };
76441
- }
76442
- function maybeStatusCode(error) {
76443
- if (typeof error !== "object" || error === null) return void 0;
76444
- const statusCode = error.statusCode;
76445
- return typeof statusCode === "number" ? statusCode : void 0;
76446
- }
76447
- //#endregion
76448
76457
  //#region ../../packages/agent-core/src/agent/context/projector.ts
76449
76458
  /** Synthetic error text used when a tool result is missing and must be
76450
76459
  * filled in so the provider accepts the message sequence. */
@@ -76972,6 +76981,14 @@ var FullCompaction = class {
76972
76981
  get compactedHistory() {
76973
76982
  return this._compactedHistory;
76974
76983
  }
76984
+ /**
76985
+ * Restore the compaction debug trail from a `context.snapshot` record. During
76986
+ * snapshot replay the pre-fold history is skipped, so `markCompleted` can no
76987
+ * longer re-render it — the snapshot carries the trail instead.
76988
+ */
76989
+ restoreCompactedHistory(entries) {
76990
+ this._compactedHistory = [...entries];
76991
+ }
76975
76992
  /** One-shot: true if session memory summary should be injected at the next step. */
76976
76993
  shouldInjectSessionSummary() {
76977
76994
  if (this._shouldInjectSessionSummary) {
@@ -77124,7 +77141,9 @@ var FullCompaction = class {
77124
77141
  }
77125
77142
  async compactionWorker(signal, data, compactedCount) {
77126
77143
  const originalHistory = [...this.agent.context.history];
77127
- const tokensBefore = estimateTokensForMessages(originalHistory);
77144
+ const systemPromptTokens = estimateTokens$1(this.agent.getRuntimeSystemPrompt());
77145
+ const toolTokens = estimateTokensForTools(this.agent.tools.loopTools);
77146
+ const tokensBefore = systemPromptTokens + toolTokens + estimateTokensForMessages(originalHistory);
77128
77147
  const model = this.agent.config.model;
77129
77148
  const isUpdate = extractPreviousSummary(originalHistory) !== null;
77130
77149
  let retryCount = 0;
@@ -77193,7 +77212,7 @@ var FullCompaction = class {
77193
77212
  for (const msg of messagesToCompactForOps) extractFileOpsFromMessage(msg, fileOps);
77194
77213
  const toolCallHistory = formatToolCallHistory(messagesToCompactForOps);
77195
77214
  const processedSummary = this.postProcessSummary(summary, fileOps, toolCallHistory, compactedCount);
77196
- const tokensAfter = estimateTokens$1(processedSummary) + estimateTokensForMessages(recent);
77215
+ const tokensAfter = systemPromptTokens + toolTokens + estimateTokens$1(processedSummary) + estimateTokensForMessages(recent);
77197
77216
  const fileLists = computeFileLists(fileOps);
77198
77217
  const MAX_PERSISTED_FILES = 100;
77199
77218
  const readFiles = fileLists.readFiles.slice(0, MAX_PERSISTED_FILES);
@@ -78901,6 +78920,42 @@ var ContextMemory = class {
78901
78920
  this.pendingToolResultIds = new Set(snapshot.pendingToolResultIds);
78902
78921
  this.deferredMessages = [...snapshot.deferredMessages];
78903
78922
  }
78923
+ /**
78924
+ * JSON-safe snapshot for wire persistence. `openSteps` values are recorded as
78925
+ * their index into `history` so restoring can rebuild the live reference
78926
+ * identity between history messages and open steps (see
78927
+ * {@link ContextMemoryJSONSnapshot}).
78928
+ */
78929
+ toJSONSnapshot() {
78930
+ return {
78931
+ history: [...this._history],
78932
+ tokenCount: this._tokenCount,
78933
+ tokenCountCoveredMessageCount: this.tokenCountCoveredMessageCount,
78934
+ openSteps: [...this.openSteps.entries()].map(([uuid, message]) => [uuid, this._history.indexOf(message)]),
78935
+ pendingToolResultIds: [...this.pendingToolResultIds],
78936
+ deferredMessages: [...this.deferredMessages]
78937
+ };
78938
+ }
78939
+ /**
78940
+ * Restore from a JSON-safe snapshot produced by {@link toJSONSnapshot}.
78941
+ * Open steps are re-attached to the exact history message objects they
78942
+ * pointed at, preserving reference identity: later `content.part`/`tool.call`
78943
+ * events and `applyCompaction` pruning operate on the same objects the
78944
+ * history array holds, exactly as they did in the live session.
78945
+ */
78946
+ restoreJSONSnapshot(snapshot) {
78947
+ this._history = [...snapshot.history];
78948
+ this._tokenCount = snapshot.tokenCount;
78949
+ this.tokenCountCoveredMessageCount = snapshot.tokenCountCoveredMessageCount;
78950
+ const openSteps = /* @__PURE__ */ new Map();
78951
+ for (const [uuid, historyIndex] of snapshot.openSteps) {
78952
+ const message = this._history[historyIndex];
78953
+ if (message !== void 0) openSteps.set(uuid, message);
78954
+ }
78955
+ this.openSteps = openSteps;
78956
+ this.pendingToolResultIds = new Set(snapshot.pendingToolResultIds);
78957
+ this.deferredMessages = [...snapshot.deferredMessages];
78958
+ }
78904
78959
  appendUserMessage(content, origin = USER_PROMPT_ORIGIN) {
78905
78960
  this.appendMessage({
78906
78961
  role: "user",
@@ -79014,6 +79069,11 @@ var ContextMemory = class {
79014
79069
  this.agent.injection.onContextCompacted(summary.compactedCount);
79015
79070
  this.agent.emitStatusUpdated();
79016
79071
  this.agent.microCompaction.reset();
79072
+ if (!this.agent.records.restoring) this.agent.records.logRecord({
79073
+ type: "context.snapshot",
79074
+ snapshot: this.toJSONSnapshot(),
79075
+ compactedHistory: [...this.agent.fullCompaction.compactedHistory]
79076
+ });
79017
79077
  }
79018
79078
  data() {
79019
79079
  return {
@@ -79071,7 +79131,16 @@ var ContextMemory = class {
79071
79131
  this.lastSentFingerprints = messages.map(messageFingerprint);
79072
79132
  if (prev.length === 0) return;
79073
79133
  const appended = messages.length - prev.length;
79074
- if (stable >= prev.length) return;
79134
+ if (stable >= prev.length) {
79135
+ if (appended > 0) this.agent.log.debug("prefix-stability: provider prompt cache prefix hit", {
79136
+ stablePrefixLength: stable,
79137
+ cachedPrefixTokens: estimateTokensForMessages(messages.slice(0, stable)),
79138
+ prevMessageCount: prev.length,
79139
+ currentMessageCount: messages.length,
79140
+ appendedSinceLast: appended
79141
+ });
79142
+ return;
79143
+ }
79075
79144
  this.agent.log.debug("prefix-stability: provider prompt cache prefix broke", {
79076
79145
  stablePrefixLength: stable,
79077
79146
  prevMessageCount: prev.length,
@@ -79192,6 +79261,30 @@ var ContextMemory = class {
79192
79261
  });
79193
79262
  }
79194
79263
  }
79264
+ /**
79265
+ * Drop in-flight assistant messages that cannot be serialized into a valid
79266
+ * provider request. An interrupted or empty step leaves an open assistant
79267
+ * message whose content is either empty or only "think" parts; after
79268
+ * projection it serializes to a message with no content and no tool_calls,
79269
+ * which strict OpenAI-compatible gateways reject with a 400 on every later
79270
+ * request. Messages carrying any sendable part (text / image / audio / video)
79271
+ * or tool calls are kept.
79272
+ */
79273
+ dropVacuousOpenMessages() {
79274
+ for (const [uuid, message] of this.openSteps) {
79275
+ if (message.content.some((part) => part.type !== "think") || message.toolCalls.length > 0) continue;
79276
+ const index = this._history.indexOf(message);
79277
+ if (index !== -1) {
79278
+ this._history.splice(index, 1);
79279
+ this.agent.injection.onContextMessageRemoved(index);
79280
+ if (index < this.tokenCountCoveredMessageCount) {
79281
+ this.tokenCountCoveredMessageCount--;
79282
+ this._tokenCount = Math.max(0, this._tokenCount - estimateTokensForMessages([message]));
79283
+ }
79284
+ }
79285
+ this.openSteps.delete(uuid);
79286
+ }
79287
+ }
79195
79288
  };
79196
79289
  function toolResultOutputForModel(result) {
79197
79290
  const output = result.output;
@@ -83027,6 +83120,14 @@ const MISSING_MEDIA_PLACEHOLDER = "[media missing]";
83027
83120
  function isBlobRef(url) {
83028
83121
  return url.startsWith(BLOBREF_PROTOCOL);
83029
83122
  }
83123
+ /**
83124
+ * Blob storage for large message content (images, files, videos). Content above
83125
+ * the size threshold is offloaded to blobs in `blobsDir` and referenced from
83126
+ * wire records as `blobref:` URLs; `rehydrateParts` resolves them back to
83127
+ * inline data when a session is loaded. A single filesystem implementation is
83128
+ * used across the engine; the class boundary is what keeps blob details out of
83129
+ * the wire/records code.
83130
+ */
83030
83131
  var BlobStore = class {
83031
83132
  blobsDir;
83032
83133
  threshold;
@@ -83075,6 +83176,33 @@ var BlobStore = class {
83075
83176
  }
83076
83177
  };
83077
83178
  }
83179
+ case "context.snapshot": {
83180
+ const history = await Promise.all(record.snapshot.history.map(async (message) => {
83181
+ const content = await this.offloadParts(message.content);
83182
+ return content === message.content ? message : {
83183
+ ...message,
83184
+ content
83185
+ };
83186
+ }));
83187
+ const deferredMessages = await Promise.all(record.snapshot.deferredMessages.map(async (message) => {
83188
+ const content = await this.offloadParts(message.content);
83189
+ return content === message.content ? message : {
83190
+ ...message,
83191
+ content
83192
+ };
83193
+ }));
83194
+ const historyChanged = history.some((message, i) => message !== record.snapshot.history[i]);
83195
+ const deferredChanged = deferredMessages.some((message, i) => message !== record.snapshot.deferredMessages[i]);
83196
+ if (!historyChanged && !deferredChanged) return record;
83197
+ return {
83198
+ ...record,
83199
+ snapshot: {
83200
+ ...record.snapshot,
83201
+ history,
83202
+ deferredMessages
83203
+ }
83204
+ };
83205
+ }
83078
83206
  default: return record;
83079
83207
  }
83080
83208
  }
@@ -83218,6 +83346,28 @@ function asMediaContainer(value) {
83218
83346
  }
83219
83347
  //#endregion
83220
83348
  //#region ../../packages/agent-core/src/agent/records/index.ts
83349
+ /**
83350
+ * Record types whose state is fully captured by a `context.snapshot` record.
83351
+ * When a snapshot exists, every one of these that predates it is skipped during
83352
+ * replay because the snapshot already holds the folded context memory. Note
83353
+ * `micro_compaction.apply` is written with an `as never` cast (it is not part of
83354
+ * the AgentRecord union), so it is matched here by its literal type string.
83355
+ *
83356
+ * `full_compaction.complete` is included because its only lasting effect is
83357
+ * pushing onto `compactedHistory` — a debug trail rendered from the pre-fold
83358
+ * history. Snapshot replay skips that pre-fold history, so the trail would be
83359
+ * re-rendered as empty; the snapshot carries the trail itself instead.
83360
+ */
83361
+ const SNAPSHOT_FOLDED_CONTEXT_TYPES = new Set([
83362
+ "context.append_message",
83363
+ "context.append_loop_event",
83364
+ "context.apply_compaction",
83365
+ "micro_compaction.apply",
83366
+ "full_compaction.complete"
83367
+ ]);
83368
+ function isSnapshotFoldedContextRecord(type) {
83369
+ return SNAPSHOT_FOLDED_CONTEXT_TYPES.has(type);
83370
+ }
83221
83371
  function restoreAgentRecord(agent, input) {
83222
83372
  switch (input.type) {
83223
83373
  case "metadata": return;
@@ -83300,6 +83450,17 @@ function restoreAgentRecord(agent, input) {
83300
83450
  case "context.apply_compaction":
83301
83451
  agent.context.applyCompaction(input);
83302
83452
  return;
83453
+ case "context.snapshot":
83454
+ agent.context.restoreJSONSnapshot(input.snapshot);
83455
+ agent.fullCompaction.restoreCompactedHistory(input.compactedHistory);
83456
+ for (const message of agent.context.history) {
83457
+ if (message.origin?.kind === "background_task") agent.background.markDeliveredNotification(message.origin);
83458
+ agent.replayBuilder.push({
83459
+ type: "message",
83460
+ message
83461
+ });
83462
+ }
83463
+ return;
83303
83464
  case "tools.register_user_tool":
83304
83465
  agent.tools.registerUserTool(input);
83305
83466
  return;
@@ -83378,8 +83539,19 @@ var AgentRecords = class {
83378
83539
  protocol_version: "1.4"
83379
83540
  };
83380
83541
  replayedRecords.push(migratedRecord);
83381
- this.restore(migratedRecord);
83382
83542
  }
83543
+ let snapshotIndex = -1;
83544
+ for (let i = replayedRecords.length - 1; i >= 0; i--) if (replayedRecords[i]?.type === "context.snapshot") {
83545
+ snapshotIndex = i;
83546
+ break;
83547
+ }
83548
+ for (let i = 0; i < replayedRecords.length; i++) {
83549
+ const record = replayedRecords[i];
83550
+ if (!record) continue;
83551
+ if (i < snapshotIndex && isSnapshotFoldedContextRecord(record.type)) continue;
83552
+ this.restore(record);
83553
+ }
83554
+ this.agent.context.dropVacuousOpenMessages();
83383
83555
  if (shouldRewrite) {
83384
83556
  this.persistence.rewrite(replayedRecords);
83385
83557
  await this.persistence.flush();
@@ -96579,6 +96751,13 @@ var ToolManager = class {
96579
96751
  getTodos() {
96580
96752
  return cloneTodos(this.store.todo ?? []);
96581
96753
  }
96754
+ /**
96755
+ * Register a user/plugin tool. This is the public entry point for any
96756
+ * third-party extension (plugins, skills, future harness adapters) to expose
96757
+ * a tool — built-in tools use the internal `builtinTools` map and should not
96758
+ * route through here. Prefer `defineTool()` for the typed high-level API;
96759
+ * this method takes a hand-written registration.
96760
+ */
96582
96761
  registerUserTool(input) {
96583
96762
  this.agent.records.logRecord({
96584
96763
  type: "tools.register_user_tool",
@@ -96614,6 +96793,10 @@ var ToolManager = class {
96614
96793
  this.userTools.delete(name);
96615
96794
  this.enabledTools.delete(name);
96616
96795
  }
96796
+ /**
96797
+ * Register an MCP server (and its tools). Public entry point for third-party
96798
+ * extensions to expose MCP-backed tools; built-in tooling does not use it.
96799
+ */
96617
96800
  registerMcpServer(serverName, client, tools, enabledTools, options) {
96618
96801
  this.unregisterMcpServer(serverName);
96619
96802
  const qualifiedNames = [];
@@ -97716,6 +97899,11 @@ var TurnFlow = class {
97716
97899
  } catch (error) {
97717
97900
  console.error("closeAbandonedToolExchange failed", error);
97718
97901
  }
97902
+ try {
97903
+ this.agent.context.dropVacuousOpenMessages();
97904
+ } catch (error) {
97905
+ console.error("dropVacuousOpenMessages failed", error);
97906
+ }
97719
97907
  if (this.currentId === turnId) this.agent.usage.endTurn();
97720
97908
  this.agent.emitEvent(ended);
97721
97909
  if (standalone && this.currentId === turnId) this.activeTurn = null;
@@ -98466,6 +98654,8 @@ var Agent = class {
98466
98654
  workingSet;
98467
98655
  dreamTracker;
98468
98656
  replayBuilder;
98657
+ /** Read-only manifest of the core engine subsystems (see {@link AgentServices}). */
98658
+ services;
98469
98659
  lastLlmConfigLogSignature;
98470
98660
  sharedEmbeddingEngine;
98471
98661
  resolveRuntimeSystemPrompt;
@@ -98518,6 +98708,25 @@ var Agent = class {
98518
98708
  this.workingSet = new WorkingSet();
98519
98709
  this.dreamTracker = new DreamTracker(screamHomeDir ?? "");
98520
98710
  this.replayBuilder = new ReplayBuilder(this);
98711
+ this.services = {
98712
+ records: this.records,
98713
+ context: this.context,
98714
+ config: this.config,
98715
+ turn: this.turn,
98716
+ injection: this.injection,
98717
+ permission: this.permission,
98718
+ planMode: this.planMode,
98719
+ usage: this.usage,
98720
+ tools: this.tools,
98721
+ skills: this.skills,
98722
+ background: this.background,
98723
+ goal: this.goal,
98724
+ sessionMemory: this.sessionMemory,
98725
+ workingSet: this.workingSet,
98726
+ fullCompaction: this.fullCompaction,
98727
+ microCompaction: this.microCompaction,
98728
+ systemPrompt: () => this.getRuntimeSystemPrompt()
98729
+ };
98521
98730
  }
98522
98731
  /**
98523
98732
  * Promise that resolves once the shared memory store (and any legacy migration)
@@ -98684,6 +98893,26 @@ var Agent = class {
98684
98893
  });
98685
98894
  };
98686
98895
  }
98896
+ /**
98897
+ * Bounded-retry wrapper around `generate` for auxiliary LLM calls (exit
98898
+ * memory extraction, side questions, knowledge-base text generation, skill
98899
+ * plan generation). These call the model directly, outside the loop's
98900
+ * step-retry layer, and SDK-level retries are disabled — without this they
98901
+ * would hard-fail on any transient 429/5xx. Mirrors the main loop's policy:
98902
+ * only retryable errors, exponential backoff, bounded attempts.
98903
+ */
98904
+ async generateWithRetry(provider, systemPrompt, tools, messages, maxAttempts = 3) {
98905
+ const delays = retryBackoffDelays(maxAttempts);
98906
+ for (let attempt = 1;; attempt++) try {
98907
+ return await this.generate(provider, systemPrompt, [...tools], [...messages]);
98908
+ } catch (error) {
98909
+ if (attempt >= maxAttempts || !isRetryableGenerateError(error)) throw error;
98910
+ const delayMs = computeDelayMs(error, delays, attempt);
98911
+ await new Promise((resolve) => {
98912
+ setTimeout(resolve, delayMs);
98913
+ });
98914
+ }
98915
+ }
98687
98916
  get llm() {
98688
98917
  const model = this.config.model;
98689
98918
  const provider = this.config.provider.withThinking(this.config.thinkingLevel);
@@ -98935,7 +99164,7 @@ var Agent = class {
98935
99164
  }).join("\n");
98936
99165
  const userPrompt = buildExitExtractionPrompt(sessionId, history.length, sampleText);
98937
99166
  try {
98938
- const response = await this.generate(this.config.provider, EXIT_EXTRACTION_SYSTEM_PROMPT, [], [{
99167
+ const response = await this.generateWithRetry(this.config.provider, EXIT_EXTRACTION_SYSTEM_PROMPT, [], [{
98939
99168
  role: "user",
98940
99169
  content: [{
98941
99170
  type: "text",
@@ -98984,7 +99213,7 @@ var Agent = class {
98984
99213
  const conversationContext = contextParts.join("\n\n");
98985
99214
  const system = conversationContext ? `${SIDE_QUESTION_SYSTEM}\n\n<conversation_context>\n${conversationContext}\n</conversation_context>` : SIDE_QUESTION_SYSTEM;
98986
99215
  if (!this.config.hasModel) return "No model configured. Run `scream config` or use `/model` to set a default model.";
98987
- return (await this.generate(this.config.provider, system, [], [{
99216
+ return (await this.generateWithRetry(this.config.provider, system, [], [{
98988
99217
  role: "user",
98989
99218
  content: [{
98990
99219
  type: "text",
@@ -99000,7 +99229,7 @@ var Agent = class {
99000
99229
  */
99001
99230
  async generateText(systemPrompt, userPrompt) {
99002
99231
  if (!this.config.hasModel) throw new Error("No model configured. Run `scream config` or use `/model` to set a default model.");
99003
- return (await this.generate(this.config.provider, systemPrompt, [], [{
99232
+ return (await this.generateWithRetry(this.config.provider, systemPrompt, [], [{
99004
99233
  role: "user",
99005
99234
  content: [{
99006
99235
  type: "text",
@@ -123281,8 +123510,8 @@ function getCtrlCHint() {
123281
123510
  }
123282
123511
  const MAIN_AGENT_ID$1 = "main";
123283
123512
  const EXIT_CONFIRM_WINDOW_MS = 1500;
123284
- /** Partner model-provider page opened by Ctrl+F while the chat is empty. */
123285
- const EMPTY_SESSION_HINT_URL = "https://opencode.ai/go?ref=75NKVRZQCY";
123513
+ /** Repository page opened by Ctrl+F while the chat is empty (feedback / star). */
123514
+ const EMPTY_SESSION_HINT_URL = "https://github.com/LIUTod/scream-code";
123286
123515
  const SESSION_TIPS = [
123287
123516
  {
123288
123517
  i18nKey: "editor.tip_ad",
@@ -123355,6 +123584,7 @@ function isManagedUsageProvider(providerKey) {
123355
123584
  const STREAMING_ARGS_FIELD_RE = /"(path|file_path|command|pattern|query|url|description|title|name)"\s*:\s*"((?:\\.|[^"\\])*)"/g;
123356
123585
  const STREAMING_ARGS_PREVIEW_MAX_CHARS = 8 * 1024;
123357
123586
  const STREAMING_ARGS_BUFFER_MAX_CHARS = 1024 * 1024;
123587
+ const CHARS_PER_TOKEN = 2.5;
123358
123588
  //#endregion
123359
123589
  //#region src/tui/utils/event-payload.ts
123360
123590
  function appendStreamingArgsPreview(current, next) {
@@ -124789,7 +125019,48 @@ function buildTraceCells({ wirePath }) {
124789
125019
  }
124790
125020
  finalizeStep(void 0);
124791
125021
  flushPendingSystem(void 0);
124792
- return cells;
125022
+ return capTraceSize(cells);
125023
+ }
125024
+ /**
125025
+ * Long sessions produce tens of thousands of cells with multi-MB detail
125026
+ * payloads, which previously bloated the trace HTML (up to ~60MB) and froze
125027
+ * the browser. Two mitigations, applied at build time:
125028
+ * 1. Truncate per-cell detail text (thinking/output/input/result) to a cap.
125029
+ * 2. Beyond a cell-count cap, collapse the oldest cells into per-turn
125030
+ * summary rows so the document stays bounded while early turns remain
125031
+ * visible in the ledger.
125032
+ */
125033
+ const MAX_DETAIL = 4e3;
125034
+ const MAX_CELLS = 4e3;
125035
+ function truncateDetail(value, max = MAX_DETAIL) {
125036
+ if (!value || value.length <= max) return value;
125037
+ return `${value.slice(0, max)}\n…[已截断 ${value.length - max} 字符]`;
125038
+ }
125039
+ function capTraceSize(cells) {
125040
+ for (const cell of cells) {
125041
+ cell.text = truncateDetail(cell.text, 240) ?? "";
125042
+ if (cell.thinkingDetail) cell.thinkingDetail = truncateDetail(cell.thinkingDetail);
125043
+ if (cell.outputDetail) cell.outputDetail = truncateDetail(cell.outputDetail);
125044
+ if (cell.inputDetail) cell.inputDetail = truncateDetail(cell.inputDetail);
125045
+ if (cell.result) cell.result = truncateDetail(cell.result);
125046
+ }
125047
+ if (cells.length <= MAX_CELLS) return cells;
125048
+ const keep = cells.slice(-4e3);
125049
+ const early = cells.slice(0, cells.length - MAX_CELLS);
125050
+ let firstTurn;
125051
+ let lastTurn;
125052
+ for (const cell of early) {
125053
+ if (cell.turn === void 0) continue;
125054
+ if (firstTurn === void 0 || cell.turn < firstTurn) firstTurn = cell.turn;
125055
+ if (lastTurn === void 0 || cell.turn > lastTurn) lastTurn = cell.turn;
125056
+ }
125057
+ return [{
125058
+ index: 1,
125059
+ kind: "system",
125060
+ text: `更早的轨迹已折叠${firstTurn !== void 0 && lastTurn !== void 0 ? `(回合 ${firstTurn}-${lastTurn})` : ""}:${early.length} 条记录`,
125061
+ timeSeconds: null,
125062
+ startedAt: early.find((c) => c.startedAt !== void 0 && c.startedAt !== null)?.startedAt ?? null
125063
+ }, ...keep];
124793
125064
  }
124794
125065
  function readWireRows(wirePath) {
124795
125066
  const content = readFileSync(wirePath, "utf8");
@@ -124989,6 +125260,15 @@ var collapsedCalls = false;
124989
125260
  var timeMode = false;
124990
125261
  var selectedIndex = -1;
124991
125262
  var rowEls = [];
125263
+ var PAGE = 300;
125264
+ var renderedCount = 0;
125265
+ var filtered = [];
125266
+ var shown = 0;
125267
+ var lastTurn = null;
125268
+ var turnCounts = {};
125269
+ function ensureRow(idx) {
125270
+ while (rowEls.length <= idx && renderedCount < filtered.length) renderChunk();
125271
+ }
124992
125272
  function showTip(text, x, y) {
124993
125273
  tip.innerHTML = text;
124994
125274
  tip.style.display = 'block';
@@ -125044,9 +125324,10 @@ function section(title, value, cls) {
125044
125324
  return '<div class="section"><h4>' + title + '</h4><div class="payload' + (cls ? ' ' + cls : '') + '">' + esc(value) + '</div></div>';
125045
125325
  }
125046
125326
  function showDetail(i) {
125327
+ ensureRow(i);
125047
125328
  if (selectedIndex === i) { hideDetail(); return; }
125048
125329
  selectedIndex = i;
125049
- var cell = cells[i];
125330
+ var cell = filtered[i];
125050
125331
  for (var k = 0; k < rowEls.length; k++) rowEls[k].classList.remove('selected');
125051
125332
  if (rowEls[i]) {
125052
125333
  rowEls[i].classList.add('selected');
@@ -125075,6 +125356,8 @@ function renderTimeline(visible) {
125075
125356
  timeline.innerHTML = '';
125076
125357
  if (visible.length < 2) return;
125077
125358
  var n = visible.length;
125359
+ // Sample spans on huge documents so the timeline strip stays light.
125360
+ var sampleStep = Math.max(1, Math.ceil(n / 1500));
125078
125361
  if (timeMode && visible.every(function (c) { return c.startedAt !== undefined; })) {
125079
125362
  var min = Infinity, max = -Infinity;
125080
125363
  for (var i = 0; i < n; i++) {
@@ -125095,13 +125378,13 @@ function renderTimeline(visible) {
125095
125378
  scaled.push([cs - min, ce - min]);
125096
125379
  }
125097
125380
  total = max - min;
125098
- for (var k = 0; k < n; k++) {
125381
+ for (var k = 0; k < n; k += sampleStep) {
125099
125382
  var span = makeSpan(visible[k], k, (scaled[k][0] / total) * 100, (scaled[k][1] - scaled[k][0]) / total * 100);
125100
125383
  timeline.appendChild(span);
125101
125384
  }
125102
125385
  } else {
125103
125386
  var widthPct = 100 / n;
125104
- for (var m = 0; m < n; m++) {
125387
+ for (var m = 0; m < n; m += sampleStep) {
125105
125388
  var sp = makeSpan(visible[m], m, m * widthPct, widthPct - 0.4);
125106
125389
  timeline.appendChild(sp);
125107
125390
  }
@@ -125161,15 +125444,25 @@ function render() {
125161
125444
  if (q && !(c.text + ' ' + (c.outputDetail || '') + ' ' + (c.thinkingDetail || '')).toLowerCase().includes(q)) return false;
125162
125445
  return true;
125163
125446
  });
125164
- var filtered = currentFiltered;
125447
+ filtered = currentFiltered;
125165
125448
  renderTimeline(filtered);
125166
125449
  tbody.innerHTML = '';
125167
125450
  rowEls = [];
125168
- var shown = 0;
125169
- var lastTurn = null;
125170
- var turnCounts = {};
125451
+ renderedCount = 0;
125452
+ shown = 0;
125453
+ lastTurn = null;
125454
+ turnCounts = {};
125171
125455
  for (var i = 0; i < filtered.length; i++) turnCounts[filtered[i].turn || 0] = (turnCounts[filtered[i].turn || 0] || 0) + 1;
125172
- for (var i2 = 0; i2 < filtered.length; i2++) {
125456
+ renderChunk();
125457
+ updateCount();
125458
+ }
125459
+ function updateCount() {
125460
+ var el = document.getElementById('count');
125461
+ if (el) el.textContent = shown + ' / ' + filtered.length + ' 条';
125462
+ }
125463
+ function renderChunk() {
125464
+ var end = Math.min(filtered.length, renderedCount + PAGE);
125465
+ for (var i2 = renderedCount; i2 < end; i2++) {
125173
125466
  var cell = filtered[i2];
125174
125467
  var turn = cell.turn || 0;
125175
125468
  var row;
@@ -125198,7 +125491,7 @@ function render() {
125198
125491
  if (turnsBtn) turnsBtn.classList.remove('on');
125199
125492
  render();
125200
125493
  var idx = currentFiltered.findIndex(function (c) { return c.turn === t; });
125201
- if (idx >= 0 && rowEls[idx]) { rowEls[idx].scrollIntoView({ block: 'center' }); showDetail(idx); }
125494
+ if (idx >= 0) { ensureRow(idx); if (rowEls[idx]) { rowEls[idx].scrollIntoView({ block: 'center' }); showDetail(idx); } }
125202
125495
  };
125203
125496
  })(turn));
125204
125497
  tbody.appendChild(trow);
@@ -125251,8 +125544,9 @@ function render() {
125251
125544
  shown++;
125252
125545
  lastTurn = turn;
125253
125546
  }
125547
+ renderedCount = end;
125254
125548
  if (!shown) tbody.innerHTML = '<tr><td colspan="2"><div class="placeholder">无匹配记录</div></td></tr>';
125255
- document.getElementById('count').textContent = shown + ' 条';
125549
+ updateCount();
125256
125550
  }
125257
125551
  if (searchInput) searchInput.addEventListener('input', render);
125258
125552
  if (turnsBtn) turnsBtn.addEventListener('click', function () { collapsedTurns = !collapsedTurns; turnsBtn.classList.toggle('on', collapsedTurns); render(); });
@@ -125295,6 +125589,7 @@ function locateAt(clientX) {
125295
125589
  var n = currentFiltered.length;
125296
125590
  if (n < 2) return;
125297
125591
  var idx = Math.round(p * (n - 1));
125592
+ ensureRow(idx);
125298
125593
  if (rowEls[idx] && rowEls[idx].scrollIntoView) rowEls[idx].scrollIntoView({ block: 'center' });
125299
125594
  }
125300
125595
  function timelineRectLeft() {
@@ -125317,7 +125612,10 @@ function syncLocatorFromTable() {
125317
125612
  var trackRect = track.getBoundingClientRect();
125318
125613
  locator.style.left = (trackRect.left - timelineRectLeft() + p * trackRect.width - 1) + 'px';
125319
125614
  }
125320
- if (tablePane) tablePane.addEventListener('scroll', syncLocatorFromTable);
125615
+ if (tablePane) tablePane.addEventListener('scroll', function () {
125616
+ syncLocatorFromTable();
125617
+ if (tablePane.scrollTop + tablePane.clientHeight >= tablePane.scrollHeight - 60 && renderedCount < filtered.length) renderChunk();
125618
+ });
125321
125619
  render();
125322
125620
  syncLocatorFromTable();
125323
125621
  `;
@@ -125368,9 +125666,9 @@ function renderTraceHtml(doc) {
125368
125666
  </aside>
125369
125667
  </div>
125370
125668
  </div>
125669
+ <div class="tip" id="tip"></div>
125371
125670
  <script id="data" type="application/json">${dataJson}<\/script>
125372
125671
  <script>${RENDER_JS}<\/script>
125373
- <div class="tip" id="tip"></div>
125374
125672
  </body>
125375
125673
  </html>`;
125376
125674
  }
@@ -128795,7 +129093,7 @@ async function guidedGoalSetup(host) {
128795
129093
  host.showNotice(t("goal.storm_breaker"), t("goal.conflict_loop"));
128796
129094
  return;
128797
129095
  }
128798
- const { TextInputDialogComponent } = await import("./text-input-dialog-CYs9xQZi.mjs");
129096
+ const { TextInputDialogComponent } = await import("./text-input-dialog-D8QuZFfe.mjs");
128799
129097
  const initialDesc = await promptText(host, TextInputDialogComponent, {
128800
129098
  title: t("goal.setup_title_initial"),
128801
129099
  subtitle: t("goal.setup_desc_hint"),
@@ -128816,7 +129114,7 @@ async function guidedGoalSetup(host) {
128816
129114
  await showGoalConfigWizard(host, session, confirmed.trim() || objective, false);
128817
129115
  }
128818
129116
  async function showGoalConfigWizard(host, session, objective, replace) {
128819
- const { TextInputDialogComponent } = await import("./text-input-dialog-CYs9xQZi.mjs");
129117
+ const { TextInputDialogComponent } = await import("./text-input-dialog-D8QuZFfe.mjs");
128820
129118
  const turnInput = await promptNumber(host, TextInputDialogComponent, {
128821
129119
  title: t("goal.wizard_title", { objective }),
128822
129120
  subtitle: t("goal.budget_turns_hint"),
@@ -133631,6 +133929,42 @@ function confirmCcConnectUninstall(host, summary) {
133631
133929
  });
133632
133930
  }
133633
133931
  //#endregion
133932
+ //#region src/cli/update/prefix.ts
133933
+ /**
133934
+ * The npm global prefix the running Scream Code was installed into, derived
133935
+ * from the entry script path. Example:
133936
+ *
133937
+ * /Users/tod/.npm-global/lib/node_modules/scream-code/dist/main.mjs
133938
+ * → prefix /Users/tod/.npm-global
133939
+ *
133940
+ * `npm install -g` without `--prefix` uses the user's configured npm prefix,
133941
+ * which may point at a root-owned directory (e.g. /usr/local) and fail with
133942
+ * EACCES even though Scream Code itself lives in a user-writable prefix.
133943
+ * Returns undefined when the layout is unrecognized — the install then falls
133944
+ * back to the default prefix behavior.
133945
+ */
133946
+ function globalPrefixForScream() {
133947
+ const entry = process.argv[1];
133948
+ if (!entry) return void 0;
133949
+ const parts = entry.split(path.sep);
133950
+ const idx = parts.lastIndexOf("node_modules");
133951
+ if (idx < 2 || parts[idx - 1] !== "lib") return void 0;
133952
+ return parts.slice(0, idx - 1).join(path.sep);
133953
+ }
133954
+ /**
133955
+ * Build the `npm install -g scream-code@latest` argument list, adding
133956
+ * `--prefix` when the running Scream Code's global directory can be resolved.
133957
+ */
133958
+ function installLatestArgs() {
133959
+ const prefix = globalPrefixForScream();
133960
+ return [
133961
+ "install",
133962
+ "-g",
133963
+ "scream-code@latest",
133964
+ ...prefix !== void 0 ? ["--prefix", prefix] : []
133965
+ ];
133966
+ }
133967
+ //#endregion
133634
133968
  //#region src/utils/persistence.ts
133635
133969
  /**
133636
133970
  * Small persistence helpers for CLI-owned data files.
@@ -133893,11 +134227,7 @@ async function handleUpdateCommand(host) {
133893
134227
  }
133894
134228
  host.showStatus(t("update.updating", { version: target.version }));
133895
134229
  host.showStatus(t("update.npm_install"));
133896
- const result = await runInstallStep(npmExecutable(), [
133897
- "install",
133898
- "-g",
133899
- "scream-code@latest"
133900
- ], void 0, t("update.install_label"));
134230
+ const result = await runInstallStep(npmExecutable(), installLatestArgs(), void 0, t("update.install_label"));
133901
134231
  if (!result.ok) {
133902
134232
  host.showError(`❌ ${result.message}`);
133903
134233
  return;
@@ -138184,4 +138514,4 @@ async function handleBuiltInSlashCommand(host, name, args) {
138184
138514
  }
138185
138515
  }
138186
138516
  //#endregion
138187
- export { toTerminalHyperlink as $, parseStreamingArgs as $t, highlightLines as A, CLI_USER_AGENT_PRODUCT as An, ENABLE_TERMINAL_THEME_REPORTING as At, AssistantMessageComponent as B, log as Bn, isBusy as Bt, UserMessageComponent as C, detectShellEnvironment as Cn, contrastTextHex as Ct, ToolCallComponent as D, detectInstallSource as Dn, DISABLE_TERMINAL_FOCUS_REPORTING as Dt, toggleEmptySessionHint as E, getLogDir as En, parseOsc11BackgroundTheme as Et, getSharedSpeedTracker as F, ScreamHarness as Fn, QUERY_TERMINAL_THEME as Ft, resetBreathingClock as G, SCREAM_ERROR_INFO as Gn, handleConnectCommand as Gt, WelcomeComponent as H, isScreamError as Hn, FooterComponent as Ht, SkillActivationComponent as I, MCP_OAUTH_AUTHORIZATION_URL_TOOL_UPDATE as In, TERMINAL_FOCUS_IN as It, handleExportDebugZipCommand as J, STATUS_BULLET as Jt, clearGoalState as K, handleLogoutCommand as Kt, ReadGroupComponent as L, resolveScreamHome as Ln, TERMINAL_FOCUS_OUT as Lt, CachedContainer as M, DEFAULT_CATALOG_URL as Mn, OSC11_RESPONSE as Mt, ThinkingComponent as N, fetchCatalog as Nn, OSC11_RESPONSE_PREFIX as Nt, renderDiffLines as O, CLI_COMMAND_NAME as On, DISABLE_TERMINAL_THEME_REPORTING as Ot, estimateTokens as P, saveCatalogCache as Pn, OSC11_RESPONSE_PREFIX_NO_ESC as Pt, handleTitleCommand as Q, isTodoItemShape as Qt, parseReadGroupOutput as R, MemoryMemoStore as Rn, TERMINAL_THEME_DARK as Rt, handleRevokeCommand as S, saveTuiConfig as Sn, createThemeStyles as St, isTurnElapsedEnabled as T, getInputHistoryFile as Tn, detectTerminalTheme as Tt, BREATHE_CYCLE_MS as U, isOrphanedToolCallError as Un, handleTraceCommand as Ut, AgentGroupComponent as V, resolveGlobalLogPath as Vn, isStreaming as Vt, getBreathingFrame as W, ErrorCodes as Wn, handleSearchCommand as Wt, handleForkCommand as X, argsRecord as Xt, handleExportMdCommand as Y, appendStreamingArgsPreview as Yt, handleInitCommand as Z, formatErrorMessage as Zt, readUpdateCache as _, PIXEL_PULSE_FRAMES as _n, showStatusReport as _t, handleSkillCommand as a, MAIN_AGENT_ID$1 as an, handleFusionPlanCommand as at, handleCcCommand as b, TuiLikePreferencesSchema as bn, createEditorTheme as bt, isPlanExpandable as c, getCtrlCHint as cn, handleThemeCommand as ct, handleMemoryCommand as d, getNoActiveSessionMessage as dn, showModelPicker as dt, serializeToolResultOutput as en, changeThinkingLevel as et, handleChannelCommand as f, buildSkillSlashCommands as fn, showPermissionPicker as ft, refreshUpdateCache as g, setExperimentalFlags as gn, clearInfoPanelState as gt, selectUpdateTarget as h, isExperimentalFlagEnabled as hn, supportsBalance as ht, buildRoleAdditionalText as i, EXIT_CONFIRM_WINDOW_MS as in, handleEditorCommand as it, langFromPath as j, PRODUCT_NAME as jn, OSC11_QUERY as jt, renderDiffLinesClustered as k, CLI_UI_MODE as kn, ENABLE_TERMINAL_FOCUS_REPORTING as kt, MoonLoader as l, getCtrlDHint as ln, handleWolfpackCommand as lt, handleUpdateCommand as m, sortSlashCommands as mn, refreshProviderBalance as mt, clearEvalPanelState as n, truncateErrorMessage as nn, handleAutoCommand as nt, disposeChildren as o, SESSION_TIPS as on, handleModelCommand as ot, handleMcpCommand as p, BUILTIN_SLASH_COMMANDS as pn, showSettingsSelector as pt, refineGoal as q, printableChar as qt, openUrl as r, EMPTY_SESSION_HINT_URL as rn, handleCompactCommand as rt, hasDispose as s, TIP_ROTATION_INTERVAL_MS as sn, handlePlanCommand as st, dispatchInput as t, stringValue as tn, getModelCycleLevel as tt, formatMemoryMemoForInjection as u, getLlmNotSetMessage as un, handleYoloCommand as ut, appendJsonlLine as v, PULSE_WAVE_FRAMES as vn, showUsage as vt, isEmptySessionHintDismissed as w, getDataDir as wn, getColorPalette as wt, getDaemonInstructions as x, loadTuiConfig as xn, createMarkdownTheme as xt, readJsonlFile as y, TuiConfigParseError as yn, resolveThemeSync as yt, BackgroundAgentStatusComponent as z, flushDiagnosticLogs as zn, TERMINAL_THEME_LIGHT as zt };
138517
+ export { toTerminalHyperlink as $, parseStreamingArgs as $t, highlightLines as A, CLI_UI_MODE as An, ENABLE_TERMINAL_THEME_REPORTING as At, AssistantMessageComponent as B, flushDiagnosticLogs as Bn, isBusy as Bt, UserMessageComponent as C, saveTuiConfig as Cn, contrastTextHex as Ct, ToolCallComponent as D, getLogDir as Dn, DISABLE_TERMINAL_FOCUS_REPORTING as Dt, toggleEmptySessionHint as E, getInputHistoryFile as En, parseOsc11BackgroundTheme as Et, getSharedSpeedTracker as F, saveCatalogCache as Fn, QUERY_TERMINAL_THEME as Ft, resetBreathingClock as G, ErrorCodes as Gn, handleConnectCommand as Gt, WelcomeComponent as H, resolveGlobalLogPath as Hn, FooterComponent as Ht, SkillActivationComponent as I, ScreamHarness as In, TERMINAL_FOCUS_IN as It, handleExportDebugZipCommand as J, STATUS_BULLET as Jt, clearGoalState as K, SCREAM_ERROR_INFO as Kn, handleLogoutCommand as Kt, ReadGroupComponent as L, MCP_OAUTH_AUTHORIZATION_URL_TOOL_UPDATE as Ln, TERMINAL_FOCUS_OUT as Lt, CachedContainer as M, PRODUCT_NAME as Mn, OSC11_RESPONSE as Mt, ThinkingComponent as N, DEFAULT_CATALOG_URL as Nn, OSC11_RESPONSE_PREFIX as Nt, renderDiffLines as O, detectInstallSource as On, DISABLE_TERMINAL_THEME_REPORTING as Ot, estimateTokens as P, fetchCatalog as Pn, OSC11_RESPONSE_PREFIX_NO_ESC as Pt, handleTitleCommand as Q, isTodoItemShape as Qt, parseReadGroupOutput as R, resolveScreamHome as Rn, TERMINAL_THEME_DARK as Rt, handleRevokeCommand as S, loadTuiConfig as Sn, createThemeStyles as St, isTurnElapsedEnabled as T, getDataDir as Tn, detectTerminalTheme as Tt, BREATHE_CYCLE_MS as U, isScreamError as Un, handleTraceCommand as Ut, AgentGroupComponent as V, log as Vn, isStreaming as Vt, getBreathingFrame as W, isOrphanedToolCallError as Wn, handleSearchCommand as Wt, handleForkCommand as X, argsRecord as Xt, handleExportMdCommand as Y, appendStreamingArgsPreview as Yt, handleInitCommand as Z, formatErrorMessage as Zt, readUpdateCache as _, setExperimentalFlags as _n, showStatusReport as _t, handleSkillCommand as a, EXIT_CONFIRM_WINDOW_MS as an, handleFusionPlanCommand as at, handleCcCommand as b, TuiConfigParseError as bn, createEditorTheme as bt, isPlanExpandable as c, TIP_ROTATION_INTERVAL_MS as cn, handleThemeCommand as ct, handleMemoryCommand as d, getLlmNotSetMessage as dn, showModelPicker as dt, serializeToolResultOutput as en, changeThinkingLevel as et, handleChannelCommand as f, getNoActiveSessionMessage as fn, showPermissionPicker as ft, refreshUpdateCache as g, isExperimentalFlagEnabled as gn, clearInfoPanelState as gt, selectUpdateTarget as h, sortSlashCommands as hn, supportsBalance as ht, buildRoleAdditionalText as i, EMPTY_SESSION_HINT_URL as in, handleEditorCommand as it, langFromPath as j, CLI_USER_AGENT_PRODUCT as jn, OSC11_QUERY as jt, renderDiffLinesClustered as k, CLI_COMMAND_NAME as kn, ENABLE_TERMINAL_FOCUS_REPORTING as kt, MoonLoader as l, getCtrlCHint as ln, handleWolfpackCommand as lt, handleUpdateCommand as m, BUILTIN_SLASH_COMMANDS as mn, refreshProviderBalance as mt, clearEvalPanelState as n, truncateErrorMessage as nn, handleAutoCommand as nt, disposeChildren as o, MAIN_AGENT_ID$1 as on, handleModelCommand as ot, handleMcpCommand as p, buildSkillSlashCommands as pn, showSettingsSelector as pt, refineGoal as q, printableChar as qt, openUrl as r, CHARS_PER_TOKEN as rn, handleCompactCommand as rt, hasDispose as s, SESSION_TIPS as sn, handlePlanCommand as st, dispatchInput as t, stringValue as tn, getModelCycleLevel as tt, formatMemoryMemoForInjection as u, getCtrlDHint as un, handleYoloCommand as ut, appendJsonlLine as v, PIXEL_PULSE_FRAMES as vn, showUsage as vt, isEmptySessionHintDismissed as w, detectShellEnvironment as wn, getColorPalette as wt, getDaemonInstructions as x, TuiLikePreferencesSchema as xn, createMarkdownTheme as xt, readJsonlFile as y, PULSE_WAVE_FRAMES as yn, resolveThemeSync as yt, BackgroundAgentStatusComponent as z, MemoryMemoStore as zn, TERMINAL_THEME_LIGHT as zt };