scream-code 0.19.5 → 0.19.6

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.
@@ -5,8 +5,8 @@ const __filename = __cjsShimFileURLToPath(import.meta.url);
5
5
  const __dirname = __cjsShimDirname(__filename);
6
6
  import "./suppress-sqlite-warning-C2VB0doZ.mjs";
7
7
  import { A as sharedMemoStore } from "./src-Cu3sUIJK.mjs";
8
- import { $n as validateFeishuCredentials, A as langFromPath, An as hasEmbeddingModelCache, Ar as resolveGlobalLogPath, At as createThemeStyles, B as getSharedSpeedTracker, Bn as isSendThrottled, Bt as OSC11_RESPONSE, Cn as BUILTIN_SLASH_COMMANDS, Cr as ScreamHarness, D as renderDiffLines, Dn as embeddingProgressLabel, Dr as resolveScreamHome, Dt as isEmptySessionHintDismissed, E as ToolCallComponent, En as setExperimentalFlags, Er as isRealUserPrompt, Et as createMarkdownTheme, F as SkillActivationComponent, Fn as startLineDaemonDetached, Ft as DISABLE_TERMINAL_FOCUS_REPORTING, G as AgentGroupComponent, Gn as parseAesKey, Gt as TERMINAL_FOCUS_OUT, H as lerpGradient, Ht as OSC11_RESPONSE_PREFIX_NO_ESC, I as AssistantMessageComponent, In as stopLineDaemon, It as DISABLE_TERMINAL_THEME_REPORTING, J as getBreathingFrame, Jn as TuiConfigParseError, Jt as safeUsageRatio, K as WelcomeComponent, Kn as replaceTabs, Kt as TERMINAL_THEME_DARK, L as ActivityGroupComponent, Ln as UPLOAD_MEDIA_TYPE, Lt as ENABLE_TERMINAL_FOCUS_REPORTING, M as ThinkingComponent, Mn as PIXEL_PULSE_FRAMES, Mr as isOrphanedToolCallError, Mt as getColorPalette, N as NoticeMessageComponent, Nn as PULSE_WAVE_FRAMES, Nr as SCREAM_ERROR_INFO, Nt as detectTerminalTheme, O as renderDiffLinesClustered, On as embeddingFailureDetail, Or as flushDiagnosticLogs, Ot as isTurnElapsedEnabled, P as StatusMessageComponent, Pn as readLineDaemonStatus, Pt as parseOsc11BackgroundTheme, Qn as feishuFileType, R as charsForTokenBudget, Rn as WeixinApiError, Rt as ENABLE_TERMINAL_THEME_REPORTING, S as readJsonlFile, Sn as buildSkillSlashCommands, Sr as saveCatalogCache, T as UserMessageComponent, Tn as isExperimentalFlagEnabled, Tt as createEditorTheme, U as lerpHex, Un as buildCdnDownloadUrl, Ut as QUERY_TERMINAL_THEME, V as GRADIENT_CYCLE_MS, Vn as validateWeixinToken, Vt as OSC11_RESPONSE_PREFIX, W as BackgroundAgentStatusComponent, Wn as decryptAesEcb, Wt as TERMINAL_FOCUS_IN, X as CompactionComponent, Xn as FeishuClient, Y as resetBreathingClock, Yn as loadTuiConfig, Yt as SubagentSlots, Z as clearGoalState, Zn as FeishuCredentialError, _n as TIP_ROTATION_INTERVAL_MS, _r as CLI_UI_MODE, a as writeTextClipboard, an as appendStreamingArgsPreview, ar as getWeixinCursorFile, at as getModelCycleLevel, b as readUpdateCache, bn as getLlmNotSetMessage, br as DEFAULT_CATALOG_URL, bt as supportsBalance, cn as isTodoItemShape, cr as resolveCustomCommands, d as isExpandable, dn as stringValue, dr as detectShellEnvironment, en as isBusy, er as LineConfigError, f as isPlanExpandable, fn as truncateErrorMessage, fr as getDataDir, ft as handlePlanCommand, gn as SESSION_TIPS, gr as CLI_COMMAND_NAME, hn as MAIN_AGENT_ID, hr as detectInstallSource, i as openUrl, in as appendSessionHeaderHint, ir as getWeixinContextTokensFile, it as changeThinkingLevel, j as CachedContainer, jn as startManualEmbeddingDownload, jr as isScreamError, jt as contrastTextHex, k as highlightLines, kn as getKnowledgeStore, kr as log, kt as toggleEmptySessionHint, l as disposeChildren, ln as parseStreamingArgs, lr as resolveFeishuOptions, m as formatMemoryMemoForInjection, mn as EXIT_CONFIRM_WINDOW_MS, mr as getLogDir, n as clearEvalPanelState, nn as printableChar, nr as getLineConfigPath, o as syncDiagramCapabilityPrompt, on as argsRecord, or as getWeixinStateDir, p as MoonLoader, pr as getInputHistoryFile, q as BREATHE_CYCLE_MS, qn as sanitizeShellOutput, qt as TERMINAL_THEME_LIGHT, rn as STATUS_BULLET, rr as getLinePidFile, rt as toTerminalHyperlink, sn as formatErrorMessage, sr as loadLineConfig, t as dispatchInput, tn as isStreaming, tr as assertSinglePlatformConfig, u as hasDispose, un as serializeToolResultOutput, ur as resolveWeixinOptions, ut as handleFusionPlanCommand, v as selectUpdateTarget, vn as getCtrlCHint, vr as CLI_USER_AGENT_PRODUCT, wn as sortSlashCommands, wr as normalizeWorkDir, wt as resolveThemeSync, x as appendJsonlLine, xn as getNoActiveSessionMessage, xr as fetchCatalog, xt as clearInfoPanelState, y as refreshUpdateCache, yn as getCtrlDHint, yr as PRODUCT_NAME, yt as refreshProviderBalance, z as estimateTokens, zn as WeixinClient, zt as OSC11_QUERY } from "./dispatch-Brb_yK-J.mjs";
9
- import { i as t, n as getLocale, r as setLocale } from "./text-input-dialog-D6PfbOws.mjs";
8
+ import { $n as validateFeishuCredentials, A as langFromPath, An as hasEmbeddingModelCache, Ar as flushDiagnosticLogs, At as createThemeStyles, B as getSharedSpeedTracker, Bn as isSendThrottled, Bt as OSC11_RESPONSE, Cn as BUILTIN_SLASH_COMMANDS, Cr as fetchCatalog, D as renderDiffLines, Dn as embeddingProgressLabel, Dt as isEmptySessionHintDismissed, E as ToolCallComponent, En as setExperimentalFlags, Er as normalizeWorkDir, Et as createMarkdownTheme, F as SkillActivationComponent, Fn as startLineDaemonDetached, Fr as SCREAM_ERROR_INFO, Ft as DISABLE_TERMINAL_FOCUS_REPORTING, G as AgentGroupComponent, Gn as parseAesKey, Gt as TERMINAL_FOCUS_OUT, H as lerpGradient, Ht as OSC11_RESPONSE_PREFIX_NO_ESC, I as AssistantMessageComponent, In as stopLineDaemon, It as DISABLE_TERMINAL_THEME_REPORTING, J as getBreathingFrame, Jn as TuiConfigParseError, Jt as safeUsageRatio, K as WelcomeComponent, Kn as replaceTabs, Kt as TERMINAL_THEME_DARK, L as ActivityGroupComponent, Ln as UPLOAD_MEDIA_TYPE, Lt as ENABLE_TERMINAL_FOCUS_REPORTING, M as ThinkingComponent, Mn as PIXEL_PULSE_FRAMES, Mr as resolveGlobalLogPath, Mt as getColorPalette, N as NoticeMessageComponent, Nn as PULSE_WAVE_FRAMES, Nr as isScreamError, Nt as detectTerminalTheme, O as renderDiffLinesClustered, On as embeddingFailureDetail, Or as isRealUserPrompt, Ot as isTurnElapsedEnabled, P as StatusMessageComponent, Pn as readLineDaemonStatus, Pr as isOrphanedToolCallError, Pt as parseOsc11BackgroundTheme, Qn as feishuFileType, R as charsForTokenBudget, Rn as WeixinApiError, Rt as ENABLE_TERMINAL_THEME_REPORTING, S as readJsonlFile, Sn as buildSkillSlashCommands, Sr as DEFAULT_CATALOG_URL, T as UserMessageComponent, Tn as isExperimentalFlagEnabled, Tr as ScreamHarness, Tt as createEditorTheme, U as lerpHex, Un as buildCdnDownloadUrl, Ut as QUERY_TERMINAL_THEME, V as GRADIENT_CYCLE_MS, Vn as validateWeixinToken, Vt as OSC11_RESPONSE_PREFIX, W as BackgroundAgentStatusComponent, Wn as decryptAesEcb, Wt as TERMINAL_FOCUS_IN, X as CompactionComponent, Xn as FeishuClient, Y as resetBreathingClock, Yn as loadTuiConfig, Yt as SubagentSlots, Z as clearGoalState, Zn as FeishuCredentialError, _n as TIP_ROTATION_INTERVAL_MS, _r as detectInstallSource, a as writeTextClipboard, an as appendStreamingArgsPreview, ar as getWeixinContextTokensFile, at as getModelCycleLevel, b as readUpdateCache, bn as getLlmNotSetMessage, br as CLI_USER_AGENT_PRODUCT, bt as supportsBalance, cn as isTodoItemShape, cr as loadLineConfig, d as isExpandable, dn as stringValue, dr as resolveTurnTimeoutMs, en as isBusy, er as LineConfigError, f as isPlanExpandable, fn as truncateErrorMessage, fr as resolveWeixinOptions, ft as handlePlanCommand, gn as SESSION_TIPS, gr as getLogDir, hn as MAIN_AGENT_ID, hr as getInputHistoryFile, i as openUrl, in as appendSessionHeaderHint, ir as getLinePidFile, it as changeThinkingLevel, j as CachedContainer, jn as startManualEmbeddingDownload, jr as log, jt as contrastTextHex, k as highlightLines, kn as getKnowledgeStore, kr as resolveScreamHome, kt as toggleEmptySessionHint, l as disposeChildren, ln as parseStreamingArgs, lr as resolveCustomCommands, m as formatMemoryMemoForInjection, mn as EXIT_CONFIRM_WINDOW_MS, mr as getDataDir, n as clearEvalPanelState, nn as printableChar, nr as assertSinglePlatformConfig, o as syncDiagramCapabilityPrompt, on as argsRecord, or as getWeixinCursorFile, p as MoonLoader, pr as detectShellEnvironment, q as BREATHE_CYCLE_MS, qn as sanitizeShellOutput, qt as TERMINAL_THEME_LIGHT, rn as STATUS_BULLET, rr as getLineConfigPath, rt as toTerminalHyperlink, sn as formatErrorMessage, sr as getWeixinStateDir, t as dispatchInput, tn as isStreaming, tr as MINUTE_MS, u as hasDispose, un as serializeToolResultOutput, ur as resolveFeishuOptions, ut as handleFusionPlanCommand, v as selectUpdateTarget, vn as getCtrlCHint, vr as CLI_COMMAND_NAME, wn as sortSlashCommands, wr as saveCatalogCache, wt as resolveThemeSync, x as appendJsonlLine, xn as getNoActiveSessionMessage, xr as PRODUCT_NAME, xt as clearInfoPanelState, y as refreshUpdateCache, yn as getCtrlDHint, yr as CLI_UI_MODE, yt as refreshProviderBalance, z as estimateTokens, zn as WeixinClient, zt as OSC11_QUERY } from "./dispatch-XPKo0cQR.mjs";
9
+ import { i as t, n as getLocale, r as setLocale } from "./text-input-dialog-BqMy3ifH.mjs";
10
10
  import { createRequire } from "node:module";
11
11
  import { createHash, randomInt, randomUUID } from "node:crypto";
12
12
  import { mkdir, mkdtemp, open, readFile, realpath, rm, stat, writeFile } from "node:fs/promises";
@@ -28,7 +28,7 @@ function optionalBuildString(value) {
28
28
  return typeof value === "string" && value.length > 0 ? value : void 0;
29
29
  }
30
30
  const SCREAM_BUILD_INFO = {
31
- version: optionalBuildString("0.19.5"),
31
+ version: optionalBuildString("0.19.6"),
32
32
  channel: optionalBuildString(""),
33
33
  commit: optionalBuildString(""),
34
34
  buildTarget: optionalBuildString("darwin-arm64")
@@ -1958,6 +1958,7 @@ async function statusText$1(deps) {
1958
1958
  `模式:${modes.join(" · ")}`,
1959
1959
  `上下文:${percent}(${formatTokens(status.contextTokens)}/${formatTokens(status.maxContextTokens)})`,
1960
1960
  `思考级别:${status.thinkingLevel}`,
1961
+ ...deps.turnTimeoutMinutes === void 0 ? [] : [`单轮上限:${deps.turnTimeoutMinutes} 分钟`],
1961
1962
  ...deps.voiceStatus === void 0 || deps.voiceStatus === null ? [] : [deps.voiceStatus]
1962
1963
  ].join("\n");
1963
1964
  } catch (error) {
@@ -2228,8 +2229,11 @@ var LineTurnCollector = class {
2228
2229
  * - one forward at a time per session; a second fire during collection is
2229
2230
  * skipped rather than interleaved.
2230
2231
  */
2231
- /** A fired turn that never reports its end must not block later fires. */
2232
- const DEFAULT_COLLECT_TIMEOUT_MS = 15 * 6e4;
2232
+ /**
2233
+ * A fired turn that never reports its end must not block later fires. Follows
2234
+ * the channel's turn cap, so a long scheduled task is not dropped early.
2235
+ */
2236
+ const DEFAULT_COLLECT_TIMEOUT_MS = 60 * MINUTE_MS;
2233
2237
  var CronRelay = class {
2234
2238
  options;
2235
2239
  collector;
@@ -2321,16 +2325,13 @@ var CronRelay = class {
2321
2325
  */
2322
2326
  const MAX_QUEUE_PER_SESSION = 3;
2323
2327
  const ORPHAN_RESET_NOTICE = "会话已自动重置,请重新发送你的消息。";
2324
- /** A turn that never settles is cancelled after this long (product default). */
2325
- const TURN_TIMEOUT_MS = 900 * 1e3;
2326
2328
  /**
2327
2329
  * `/stop` interrupts in-process. A tool that ignores the abort would otherwise
2328
- * keep the chat busy until the 15-minute cap, so after this window the live
2329
- * session is closed: history stays on disk and the next message resumes the same
2330
- * session id — the same end result as tearing down the agent process.
2330
+ * keep the chat busy until the turn cap, so after this window the live session is
2331
+ * closed: history stays on disk and the next message resumes the same session
2332
+ * id — the same end result as tearing down the agent process.
2331
2333
  */
2332
2334
  const STOP_ESCALATION_MS = 1e4;
2333
- const TURN_TIMEOUT_TEXT = "本轮执行超时(15 分钟),已取消。请重试或拆分任务。";
2334
2335
  /** `exec`-type custom commands are bounded like any other IM command. */
2335
2336
  const CUSTOM_COMMAND_TIMEOUT_MS = 3e4;
2336
2337
  const CUSTOM_COMMAND_MAX_BUFFER = 1024 * 1024;
@@ -2384,9 +2385,12 @@ var LineSessionDriver = class {
2384
2385
  sessionCreations = /* @__PURE__ */ new Map();
2385
2386
  /** Per-chat lifecycle mutex: session creation must never interleave a reset. */
2386
2387
  lifecycleLocks = /* @__PURE__ */ new Map();
2388
+ /** Wall-clock cap for one turn; see `turnDeadline`. */
2389
+ turnTimeoutMs;
2387
2390
  closed = false;
2388
2391
  constructor(options) {
2389
2392
  this.options = options;
2393
+ this.turnTimeoutMs = options.turnTimeoutMs ?? 36e5;
2390
2394
  }
2391
2395
  async init() {
2392
2396
  const harness = new ScreamHarness({
@@ -2575,7 +2579,7 @@ var LineSessionDriver = class {
2575
2579
  return outcome;
2576
2580
  }
2577
2581
  /**
2578
- * Resolves after `TURN_TIMEOUT_MS`. Raced against the turn promise so a
2582
+ * Resolves after the configured turn cap. Raced against the turn promise so a
2579
2583
  * provider that never emits a settlement event cannot wedge the chat queue.
2580
2584
  *
2581
2585
  * The timer belongs to this turn, not to the driver: chats run in parallel,
@@ -2586,7 +2590,7 @@ var LineSessionDriver = class {
2586
2590
  let timer;
2587
2591
  return {
2588
2592
  promise: new Promise((resolve) => {
2589
- timer = setTimeout(resolve, TURN_TIMEOUT_MS);
2593
+ timer = setTimeout(resolve, this.turnTimeoutMs);
2590
2594
  timer.unref?.();
2591
2595
  }),
2592
2596
  clear: () => {
@@ -2595,6 +2599,13 @@ var LineSessionDriver = class {
2595
2599
  }
2596
2600
  };
2597
2601
  }
2602
+ /** The cap in whole minutes, for `/status` and the timeout reply. */
2603
+ get turnTimeoutMinutes() {
2604
+ return Math.max(1, Math.round(this.turnTimeoutMs / 6e4));
2605
+ }
2606
+ turnTimeoutText() {
2607
+ return `本轮执行超时(${this.turnTimeoutMinutes} 分钟),已取消。请重试或拆分任务。`;
2608
+ }
2598
2609
  /** Close all sessions and the harness (daemon shutdown). */
2599
2610
  async close() {
2600
2611
  this.closed = true;
@@ -2666,7 +2677,7 @@ var LineSessionDriver = class {
2666
2677
  await session.cancel().catch(() => {});
2667
2678
  return {
2668
2679
  ok: false,
2669
- text: TURN_TIMEOUT_TEXT
2680
+ text: this.turnTimeoutText()
2670
2681
  };
2671
2682
  }
2672
2683
  } finally {
@@ -2812,7 +2823,8 @@ var LineSessionDriver = class {
2812
2823
  this.stopCronForwarder(sessionKey);
2813
2824
  const relay = new CronRelay({
2814
2825
  send: (text) => this.proactiveSender?.(sessionKey, text) ?? Promise.resolve("no-target"),
2815
- isBusy: () => this.activeTurns.has(sessionKey)
2826
+ isBusy: () => this.activeTurns.has(sessionKey),
2827
+ collectTimeoutMs: this.turnTimeoutMs
2816
2828
  });
2817
2829
  let pendingStart;
2818
2830
  let cronTurnId;
@@ -2870,6 +2882,7 @@ var LineSessionDriver = class {
2870
2882
  stopTurn: () => this.stopActiveTurn(sessionKey),
2871
2883
  cancelSession: () => this.cancelSession(sessionKey),
2872
2884
  voiceStatus: describeVoiceSupport(this.voiceSupport),
2885
+ turnTimeoutMinutes: this.turnTimeoutMinutes,
2873
2886
  getSession: () => this.resolveSession(sessionKey),
2874
2887
  resetSession: () => this.resetSession(sessionKey),
2875
2888
  commands: this.options.commands ?? [],
@@ -4033,8 +4046,10 @@ async function runLineDaemon() {
4033
4046
  permissionMode: lineConfig.permissionMode,
4034
4047
  workDir: lineConfig.workDir,
4035
4048
  platform: lineConfig.feishu !== void 0 ? "feishu" : "weixin",
4036
- commands: resolveCustomCommands(lineConfig.commands)
4049
+ commands: resolveCustomCommands(lineConfig.commands),
4050
+ turnTimeoutMs: resolveTurnTimeoutMs(lineConfig)
4037
4051
  });
4052
+ out$1(`单轮上限:${Math.round(resolveTurnTimeoutMs(lineConfig) / 6e4)} 分钟(config.json 的 turnTimeoutMinutes)`);
4038
4053
  const handles = [];
4039
4054
  const failures = [];
4040
4055
  let shuttingDown = false;
@@ -20187,7 +20202,7 @@ var ScreamTUI = class {
20187
20202
  const card = new OnboardingCardComponent({
20188
20203
  colors: this.state.theme.colors,
20189
20204
  onConfigure: () => {
20190
- import("./dispatch-Cqw-jMk5.mjs").then(({ handleConnectCommand }) => handleConnectCommand(this, "")).finally(() => {
20205
+ import("./dispatch-DNYdiEo4.mjs").then(({ handleConnectCommand }) => handleConnectCommand(this, "")).finally(() => {
20191
20206
  this.restoreEditor();
20192
20207
  onDone?.();
20193
20208
  });
@@ -3,5 +3,5 @@ import { fileURLToPath as __cjsShimFileURLToPath } from 'node:url';
3
3
  import { dirname as __cjsShimDirname } from 'node:path';
4
4
  const __filename = __cjsShimFileURLToPath(import.meta.url);
5
5
  const __dirname = __cjsShimDirname(__filename);
6
- import { Qt as handleConnectCommand } from "./dispatch-Brb_yK-J.mjs";
6
+ import { Qt as handleConnectCommand } from "./dispatch-XPKo0cQR.mjs";
7
7
  export { handleConnectCommand };