scream-code 0.19.6 → 0.19.8
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.
- package/README.md +24 -3
- package/dist/{app-CE9aji1S.mjs → app-BK_bW4ee.mjs} +124 -80
- package/dist/{dispatch-DNYdiEo4.mjs → dispatch-DD8Vu4Qc.mjs} +1 -1
- package/dist/{dispatch-XPKo0cQR.mjs → dispatch-DMntc47e.mjs} +1336 -348
- package/dist/main.mjs +1 -1
- package/dist/{text-input-dialog-CbYhsAbz.mjs → text-input-dialog-BLUlZjUL.mjs} +1 -1
- package/dist/{text-input-dialog-BqMy3ifH.mjs → text-input-dialog-Ce2AEFU9.mjs} +2 -0
- package/docs/plugins.md +16 -1
- package/docs/sessions.md +10 -1
- package/docs/skills.md +4 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -18,9 +18,30 @@
|
|
|
18
18
|
<a href="README.zh.md">简体中文</a>
|
|
19
19
|
</p>
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
### ❤️Sponsor
|
|
22
|
+
|
|
23
|
+
<details open>
|
|
24
|
+
<summary>Click to collapse</summary>
|
|
25
|
+
|
|
26
|
+
<table>
|
|
27
|
+
<tr>
|
|
28
|
+
<td width="210" align="center" valign="middle"><a href="https://todapi.work"><img src="assets/sponsor-todapi.png" alt="todapi" width="190"></a></td>
|
|
29
|
+
<td>
|
|
30
|
+
|
|
31
|
+
<p><strong>todapi</strong> — a high-value API gateway.</p>
|
|
32
|
+
<p>DeepSeek and other mainstream models from <strong>as low as 10% of list price</strong>, reached through one unified gateway: pay-as-you-go, one API key for multiple models. Powered by tier-one vendor resources with stable routes and strong value.</p>
|
|
33
|
+
<ul>
|
|
34
|
+
<li><strong>Price</strong>: DeepSeek and more from 10% of list price</li>
|
|
35
|
+
<li><strong>Access</strong>: one gateway, one key — switching models no longer means switching providers</li>
|
|
36
|
+
<li><strong>Get started</strong>: sign up at <a href="https://todapi.work">todapi.work</a></li>
|
|
37
|
+
</ul>
|
|
38
|
+
<p>Thanks to <a href="https://todapi.work">todapi</a> for sponsoring this project ❤️</p>
|
|
39
|
+
|
|
40
|
+
</td>
|
|
41
|
+
</tr>
|
|
42
|
+
</table>
|
|
43
|
+
|
|
44
|
+
</details>
|
|
24
45
|
|
|
25
46
|
---
|
|
26
47
|
|
|
@@ -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,
|
|
9
|
-
import { i as t, n as getLocale, r as setLocale } from "./text-input-dialog-
|
|
8
|
+
import { $n as validateFeishuCredentials, A as langFromPath, An as hasEmbeddingModelCache, At as createThemeStyles, B as getSharedSpeedTracker, Bn as isSendThrottled, Bt as OSC11_RESPONSE, Cn as BUILTIN_SLASH_COMMANDS, Cr as fetchCatalogWithMeta, D as renderDiffLines, Dn as embeddingProgressLabel, Dr as saveCatalogCacheMeta, Dt as isEmptySessionHintDismissed, E as ToolCallComponent, En as setExperimentalFlags, Er as saveCatalogCache, Et as createMarkdownTheme, F as SkillActivationComponent, Fn as startLineDaemonDetached, Fr as resolveGlobalLogPath, 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, Ir as isScreamError, 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, Lr as isOrphanedToolCallError, Lt as ENABLE_TERMINAL_FOCUS_REPORTING, M as ThinkingComponent, Mn as PIXEL_PULSE_FRAMES, Mr as resolveScreamHome, Mt as getColorPalette, N as NoticeMessageComponent, Nn as PULSE_WAVE_FRAMES, Nr as flushDiagnosticLogs, Nt as detectTerminalTheme, O as renderDiffLinesClustered, On as embeddingFailureDetail, Or as ScreamHarness, Ot as isTurnElapsedEnabled, P as StatusMessageComponent, Pn as readLineDaemonStatus, Pr as log, Pt as parseOsc11BackgroundTheme, Qn as feishuFileType, R as charsForTokenBudget, Rn as WeixinApiError, Rr as SCREAM_ERROR_INFO, 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 loadCatalogCacheMeta, 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 isRealUserPrompt, jt as contrastTextHex, k as highlightLines, kn as getKnowledgeStore, kr as normalizeWorkDir, 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 loadCatalogCache, 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-DMntc47e.mjs";
|
|
9
|
+
import { i as t, n as getLocale, r as setLocale } from "./text-input-dialog-Ce2AEFU9.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.
|
|
31
|
+
version: optionalBuildString("0.19.8"),
|
|
32
32
|
channel: optionalBuildString(""),
|
|
33
33
|
commit: optionalBuildString(""),
|
|
34
34
|
buildTarget: optionalBuildString("darwin-arm64")
|
|
@@ -5146,6 +5146,8 @@ async function autoStartLineDaemonIfConfigured() {
|
|
|
5146
5146
|
}
|
|
5147
5147
|
//#endregion
|
|
5148
5148
|
//#region src/tui/controllers/auth-flow.ts
|
|
5149
|
+
/** Skip the startup refresh when the cached snapshot is younger than this. */
|
|
5150
|
+
const CATALOG_REFRESH_INTERVAL_MS = 1440 * 60 * 1e3;
|
|
5149
5151
|
var AuthFlowController = class {
|
|
5150
5152
|
host;
|
|
5151
5153
|
constructor(host) {
|
|
@@ -5165,8 +5167,23 @@ var AuthFlowController = class {
|
|
|
5165
5167
|
* existing cache (or built-in) keeps working. Never throws.
|
|
5166
5168
|
*/
|
|
5167
5169
|
async prefetchCatalogCache() {
|
|
5170
|
+
const home = resolveScreamHome();
|
|
5171
|
+
const meta = loadCatalogCacheMeta(home);
|
|
5172
|
+
if (meta.fetchedAt !== void 0 && Date.now() - Date.parse(meta.fetchedAt) < CATALOG_REFRESH_INTERVAL_MS && loadCatalogCache(home) !== void 0) return;
|
|
5168
5173
|
try {
|
|
5169
|
-
|
|
5174
|
+
const result = await fetchCatalogWithMeta(DEFAULT_CATALOG_URL, meta.etag === void 0 ? {} : { etag: meta.etag });
|
|
5175
|
+
const fetchedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
5176
|
+
if (result.notModified) {
|
|
5177
|
+
saveCatalogCacheMeta(home, meta.etag === void 0 ? { fetchedAt } : {
|
|
5178
|
+
fetchedAt,
|
|
5179
|
+
etag: meta.etag
|
|
5180
|
+
});
|
|
5181
|
+
return;
|
|
5182
|
+
}
|
|
5183
|
+
if (result.catalog !== void 0) saveCatalogCache(result.catalog, home, result.etag === void 0 ? { fetchedAt } : {
|
|
5184
|
+
fetchedAt,
|
|
5185
|
+
etag: result.etag
|
|
5186
|
+
});
|
|
5170
5187
|
} catch {}
|
|
5171
5188
|
}
|
|
5172
5189
|
async activateModelAfterLogin(model, thinkingLevel) {
|
|
@@ -7112,7 +7129,6 @@ var SessionEventHandler = class {
|
|
|
7112
7129
|
providerLatencyWindow = 3;
|
|
7113
7130
|
renderedSkillActivationIds = /* @__PURE__ */ new Set();
|
|
7114
7131
|
renderedMcpServerStatusKeys = /* @__PURE__ */ new Map();
|
|
7115
|
-
mcpServerStatusSpinners = /* @__PURE__ */ new Map();
|
|
7116
7132
|
/**
|
|
7117
7133
|
* `SendSubagentMessage` tool call → target agent id. Needed at result time
|
|
7118
7134
|
* because `SubagentSlots.onMessagingEnd()` deletes its own mapping, and a
|
|
@@ -7140,7 +7156,6 @@ var SessionEventHandler = class {
|
|
|
7140
7156
|
this.recentSubagentInstances.length = 0;
|
|
7141
7157
|
this.renderedSkillActivationIds.clear();
|
|
7142
7158
|
this.renderedMcpServerStatusKeys.clear();
|
|
7143
|
-
this.stopAllMcpServerStatusSpinners();
|
|
7144
7159
|
this.pendingSkillCandidates = [];
|
|
7145
7160
|
this.promptedSkillCandidates.clear();
|
|
7146
7161
|
this.goalJudgeCallId = void 0;
|
|
@@ -7198,7 +7213,11 @@ var SessionEventHandler = class {
|
|
|
7198
7213
|
this.renderedMcpServerStatusKeys.set(server.name, mcpServerStatusKey(server));
|
|
7199
7214
|
hidden.push(server);
|
|
7200
7215
|
}
|
|
7201
|
-
if (hidden.length > 0)
|
|
7216
|
+
if (hidden.length > 0) {
|
|
7217
|
+
const summary = formatMcpStartupStatusSummary(hidden, visible.length);
|
|
7218
|
+
if (hidden.some((server) => server.status === "failed" || server.status === "needs-auth")) host.showStatus(summary, host.state.theme.colors.textMuted);
|
|
7219
|
+
else host.showMcpActivity?.(summary, host.state.theme.colors.textMuted);
|
|
7220
|
+
}
|
|
7202
7221
|
}
|
|
7203
7222
|
handleEvent(event, sendQueued) {
|
|
7204
7223
|
if (stampsActivity(event)) this.host.state.lastActivityAt = Date.now();
|
|
@@ -7308,17 +7327,6 @@ var SessionEventHandler = class {
|
|
|
7308
7327
|
default: break;
|
|
7309
7328
|
}
|
|
7310
7329
|
}
|
|
7311
|
-
stopAllMcpServerStatusSpinners() {
|
|
7312
|
-
const { state } = this.host;
|
|
7313
|
-
const children = state.transcriptContainer.children;
|
|
7314
|
-
for (const spinner of this.mcpServerStatusSpinners.values()) {
|
|
7315
|
-
spinner.stop();
|
|
7316
|
-
const idx = children.indexOf(spinner);
|
|
7317
|
-
if (idx >= 0) children.splice(idx, 1);
|
|
7318
|
-
}
|
|
7319
|
-
if (this.mcpServerStatusSpinners.size > 0) state.transcriptContainer.invalidate();
|
|
7320
|
-
this.mcpServerStatusSpinners.clear();
|
|
7321
|
-
}
|
|
7322
7330
|
/** Read-only snapshot of the sidebar subagent slots (8 default types +
|
|
7323
7331
|
* extras in spawn order). Consumed by the sidebar data provider. */
|
|
7324
7332
|
getSubagentSlots() {
|
|
@@ -7860,6 +7868,12 @@ var SessionEventHandler = class {
|
|
|
7860
7868
|
handleSessionWarning(event) {
|
|
7861
7869
|
this.host.showStatus(t("handler.warning_prefix", { message: event.message }), this.host.state.theme.colors.warning);
|
|
7862
7870
|
}
|
|
7871
|
+
/**
|
|
7872
|
+
* MCP server status goes to the status row above the editor — a transient
|
|
7873
|
+
* notice with its own TTL (same design as the collaboration ticker), not a
|
|
7874
|
+
* permanent transcript row. Failures / auth requests stay in the transcript
|
|
7875
|
+
* because they need user action and must not vanish after a few seconds.
|
|
7876
|
+
*/
|
|
7863
7877
|
renderMcpServerStatus(server) {
|
|
7864
7878
|
const { state } = this.host;
|
|
7865
7879
|
const key = mcpServerStatusKey(server);
|
|
@@ -7869,63 +7883,29 @@ var SessionEventHandler = class {
|
|
|
7869
7883
|
switch (server.status) {
|
|
7870
7884
|
case "connected": {
|
|
7871
7885
|
const toolStr = `${server.toolCount} tool${server.toolCount === 1 ? "" : "s"}`;
|
|
7872
|
-
|
|
7873
|
-
this.finalizeMcpServerStatusRow(server.name, message, colors.success);
|
|
7886
|
+
this.host.showMcpActivity?.(`MCP ${server.name} · ${toolStr}`, colors.success);
|
|
7874
7887
|
return;
|
|
7875
7888
|
}
|
|
7889
|
+
case "pending":
|
|
7890
|
+
this.host.showMcpActivity?.(t("handler.mcp_server_connecting", { name: server.name }), colors.textMuted);
|
|
7891
|
+
return;
|
|
7892
|
+
case "disabled":
|
|
7893
|
+
this.host.showMcpActivity?.(t("handler.mcp_server_disabled", { name: server.name }), colors.textMuted);
|
|
7894
|
+
return;
|
|
7876
7895
|
case "failed": {
|
|
7877
7896
|
const message = t("handler.mcp_server_failed", {
|
|
7878
7897
|
name: server.name,
|
|
7879
7898
|
error: server.error !== void 0 ? `: ${server.error}` : ""
|
|
7880
7899
|
});
|
|
7881
|
-
this.
|
|
7900
|
+
this.host.showStatus(message, colors.error);
|
|
7882
7901
|
return;
|
|
7883
7902
|
}
|
|
7884
7903
|
case "needs-auth": {
|
|
7885
7904
|
const message = t("handler.mcp_server_needs_auth", { name: server.name });
|
|
7886
|
-
this.
|
|
7905
|
+
this.host.showStatus(message, colors.warning);
|
|
7887
7906
|
return;
|
|
7888
7907
|
}
|
|
7889
|
-
case "disabled":
|
|
7890
|
-
this.finalizeMcpServerStatusRow(server.name, t("handler.mcp_server_disabled", { name: server.name }), colors.textMuted);
|
|
7891
|
-
return;
|
|
7892
|
-
case "pending":
|
|
7893
|
-
this.showMcpServerStatusSpinner(server.name);
|
|
7894
|
-
return;
|
|
7895
|
-
}
|
|
7896
|
-
}
|
|
7897
|
-
showMcpServerStatusSpinner(name) {
|
|
7898
|
-
const { state } = this.host;
|
|
7899
|
-
const label = t("handler.mcp_server_connecting", { name });
|
|
7900
|
-
const existing = this.mcpServerStatusSpinners.get(name);
|
|
7901
|
-
if (existing !== void 0) {
|
|
7902
|
-
existing.setLabel(label);
|
|
7903
|
-
return;
|
|
7904
|
-
}
|
|
7905
|
-
const tint = (s) => chalk.hex(state.theme.colors.textMuted)(s);
|
|
7906
|
-
const spinner = new MoonLoader(state.ui, tint, label);
|
|
7907
|
-
state.transcriptContainer.addChild(spinner);
|
|
7908
|
-
this.mcpServerStatusSpinners.set(name, spinner);
|
|
7909
|
-
state.ui.requestRender();
|
|
7910
|
-
}
|
|
7911
|
-
finalizeMcpServerStatusRow(name, message, color) {
|
|
7912
|
-
const { state } = this.host;
|
|
7913
|
-
const spinner = this.mcpServerStatusSpinners.get(name);
|
|
7914
|
-
if (spinner === void 0) {
|
|
7915
|
-
this.host.showStatus(message, color);
|
|
7916
|
-
return;
|
|
7917
7908
|
}
|
|
7918
|
-
spinner.stop();
|
|
7919
|
-
const container = state.transcriptContainer;
|
|
7920
|
-
const children = container.children;
|
|
7921
|
-
const idx = children.indexOf(spinner);
|
|
7922
|
-
if (idx >= 0) {
|
|
7923
|
-
children.splice(idx, 1);
|
|
7924
|
-
container.addChild(new StatusMessageComponent(message, state.theme.colors, color));
|
|
7925
|
-
container.invalidate();
|
|
7926
|
-
} else container.addChild(new StatusMessageComponent(message, state.theme.colors, color));
|
|
7927
|
-
this.mcpServerStatusSpinners.delete(name);
|
|
7928
|
-
state.ui.requestRender();
|
|
7929
7909
|
}
|
|
7930
7910
|
handleSkillActivated(event) {
|
|
7931
7911
|
if (this.renderedSkillActivationIds.has(event.activationId)) return;
|
|
@@ -8068,7 +8048,7 @@ var SessionEventHandler = class {
|
|
|
8068
8048
|
* candidate was detected. */
|
|
8069
8049
|
promptSkillCandidate(session, name, purpose) {
|
|
8070
8050
|
if (this.host.state.appState.model.trim().length === 0) return;
|
|
8071
|
-
const request = `检测到可复用过程「${name}」${purpose ? `(${purpose})` : ""}。请用 AskUserQuestion 工具询问用户是否将其保存为可复用技能(选项:生成 / 忽略)。用户选择「生成」后,用 MakeSkillPlanTool
|
|
8051
|
+
const request = `检测到可复用过程「${name}」${purpose ? `(${purpose})` : ""}。请用 AskUserQuestion 工具询问用户是否将其保存为可复用技能(选项:生成 / 忽略)。用户选择「生成」后,用 MakeSkillPlanTool 生成该技能,再用 MakeSkillApply 落盘;落盘后把 plan.verification.instructions 原样告诉用户,并说明这是装完后要跑的触发检查。选择「忽略」则直接说明已跳过。`;
|
|
8072
8052
|
session.prompt(request).catch(() => {
|
|
8073
8053
|
this.host.showStatus(`检测到可复用过程「${name}」,但询问失败。可稍后手动处理。`, this.host.state.theme.colors.warning);
|
|
8074
8054
|
});
|
|
@@ -11687,7 +11667,6 @@ var TranscriptController = class TranscriptController {
|
|
|
11687
11667
|
const { state } = this.host;
|
|
11688
11668
|
this.welcomeComponent?.stopBreathing();
|
|
11689
11669
|
const welcome = new WelcomeComponent(state.appState, state.theme.colors, state.ui);
|
|
11690
|
-
welcome.borderTitle = "Scream Code";
|
|
11691
11670
|
this.welcomeComponent = welcome;
|
|
11692
11671
|
if (state.editor.hasFirstInputFired()) welcome.stopBreathing();
|
|
11693
11672
|
state.transcriptContainer.addChild(welcome);
|
|
@@ -11877,14 +11856,14 @@ var GutterContainer = class extends Container {
|
|
|
11877
11856
|
* string and truncated to the available width.
|
|
11878
11857
|
*/
|
|
11879
11858
|
/**
|
|
11880
|
-
* Single-line row: `<wave> <label> <reminder> <activity>`,
|
|
11881
|
-
* omitted.
|
|
11859
|
+
* Single-line row: `<wave> <label> <reminder> <activity> <notice>`,
|
|
11860
|
+
* empty parts omitted.
|
|
11882
11861
|
*
|
|
11883
11862
|
* HStack cannot produce this layout: pi-tui's Text.render pads every line to
|
|
11884
11863
|
* the full row width, so each child's intrinsic width equals the full width
|
|
11885
11864
|
* and HStack's shrink distribution pushes later segments far to the right.
|
|
11886
11865
|
* Composing the line manually from the loader's unpadded frame text keeps the
|
|
11887
|
-
* segments adjacent, and it re-reads the frame (and
|
|
11866
|
+
* segments adjacent, and it re-reads the frame (and every chip) on every
|
|
11888
11867
|
* render so the wave keeps animating and the tickers update in place.
|
|
11889
11868
|
*/
|
|
11890
11869
|
var StatusLine = class {
|
|
@@ -11893,27 +11872,50 @@ var StatusLine = class {
|
|
|
11893
11872
|
labelColor;
|
|
11894
11873
|
reminder;
|
|
11895
11874
|
activity;
|
|
11875
|
+
notice;
|
|
11896
11876
|
labelCollapsesOnChip;
|
|
11897
|
-
constructor(wave, label, labelColor, reminder, activity, labelCollapsesOnChip = false) {
|
|
11877
|
+
constructor(wave, label, labelColor, reminder, activity, notice, labelCollapsesOnChip = false) {
|
|
11898
11878
|
this.wave = wave;
|
|
11899
11879
|
this.label = label;
|
|
11900
11880
|
this.labelColor = labelColor;
|
|
11901
11881
|
this.reminder = reminder;
|
|
11902
11882
|
this.activity = activity;
|
|
11883
|
+
this.notice = notice;
|
|
11903
11884
|
this.labelCollapsesOnChip = labelCollapsesOnChip;
|
|
11904
11885
|
}
|
|
11905
11886
|
render(width) {
|
|
11906
11887
|
const minWidth = Math.max(1, width);
|
|
11907
11888
|
const reminder = this.reminder?.() ?? null;
|
|
11908
11889
|
const activity = this.activity?.() ?? null;
|
|
11890
|
+
const notice = this.notice?.() ?? null;
|
|
11909
11891
|
const showLabel = !(this.labelCollapsesOnChip && (reminder !== null || activity !== null));
|
|
11910
|
-
const
|
|
11911
|
-
|
|
11912
|
-
|
|
11913
|
-
|
|
11914
|
-
|
|
11915
|
-
|
|
11892
|
+
const waveText = this.wave !== void 0 ? this.wave.getFrameText() : null;
|
|
11893
|
+
const paintChip = (chip) => {
|
|
11894
|
+
if (chip === null) return null;
|
|
11895
|
+
return chip.color === void 0 ? chip.text : chalk.hex(chip.color)(chip.text);
|
|
11896
|
+
};
|
|
11897
|
+
const reminderText = paintChip(reminder);
|
|
11898
|
+
const activityText = paintChip(activity);
|
|
11899
|
+
const noticeText = paintChip(notice);
|
|
11900
|
+
let labelText = showLabel && this.label.length > 0 ? this.labelColor === void 0 ? this.label : chalk.hex(this.labelColor)(this.label) : null;
|
|
11901
|
+
if (labelText !== null && noticeText !== null) {
|
|
11902
|
+
const fixedSegments = [
|
|
11903
|
+
waveText,
|
|
11904
|
+
reminderText,
|
|
11905
|
+
activityText,
|
|
11906
|
+
noticeText
|
|
11907
|
+
].filter((segment) => segment !== null);
|
|
11908
|
+
const room = minWidth - (1 + fixedSegments.reduce((total, segment) => total + visibleWidth(segment), 0) + fixedSegments.length * 2);
|
|
11909
|
+
labelText = room >= 2 ? truncateToWidth(labelText, room, "…") : null;
|
|
11916
11910
|
}
|
|
11911
|
+
const segments = [];
|
|
11912
|
+
if (waveText !== null) segments.push(waveText);
|
|
11913
|
+
if (labelText !== null && labelText.length > 0) segments.push(labelText);
|
|
11914
|
+
for (const chipText of [
|
|
11915
|
+
reminderText,
|
|
11916
|
+
activityText,
|
|
11917
|
+
noticeText
|
|
11918
|
+
]) if (chipText !== null) segments.push(chipText);
|
|
11917
11919
|
if (segments.length === 0) return [];
|
|
11918
11920
|
if (this.wave !== void 0 && segments.length === 1) return [truncateToWidth(segments[0], minWidth)];
|
|
11919
11921
|
return [truncateToWidth(` ${segments.join(" ")}`, minWidth)];
|
|
@@ -11942,11 +11944,11 @@ var StatusBarPaneComponent = class extends Container {
|
|
|
11942
11944
|
update(options) {
|
|
11943
11945
|
this.clear();
|
|
11944
11946
|
if (options.mode === "idle") {
|
|
11945
|
-
if (options.label.length > 0 || options.reminder !== void 0 || options.activity !== void 0) this.addChild(new StatusLine(void 0, options.label, options.labelColor, options.reminder, options.activity, true));
|
|
11947
|
+
if (options.label.length > 0 || options.reminder !== void 0 || options.activity !== void 0 || options.notice !== void 0) this.addChild(new StatusLine(void 0, options.label, options.labelColor, options.reminder, options.activity, options.notice, true));
|
|
11946
11948
|
return;
|
|
11947
11949
|
}
|
|
11948
11950
|
if (options.pulseWave !== void 0) {
|
|
11949
|
-
this.addChild(new StatusLine(options.pulseWave, options.label, options.labelColor, options.reminder, options.activity));
|
|
11951
|
+
this.addChild(new StatusLine(options.pulseWave, options.label, options.labelColor, options.reminder, options.activity, options.notice));
|
|
11950
11952
|
return;
|
|
11951
11953
|
}
|
|
11952
11954
|
if (options.label.length > 0) {
|
|
@@ -13070,6 +13072,11 @@ const COLLAB_ACTIVITY_TTL_MS = 8e3;
|
|
|
13070
13072
|
/** How long a scheduled-task reminder stays: longer than the collaboration
|
|
13071
13073
|
* chip because a cron fire is time-sensitive and must not slip by. */
|
|
13072
13074
|
const REMINDER_ACTIVITY_TTL_MS = 1e4;
|
|
13075
|
+
/** How long an MCP server notice stays on the status bar (own slot, transient
|
|
13076
|
+
* by design — startup connect chatter must not occupy the transcript).
|
|
13077
|
+
* Short on purpose: the notice appears once loading finishes and clears
|
|
13078
|
+
* quickly instead of parking on the row. */
|
|
13079
|
+
const MCP_ACTIVITY_TTL_MS = 3e3;
|
|
13073
13080
|
/** Footer git badge freshness window; the deferred read refreshes past it. */
|
|
13074
13081
|
const GIT_DIFF_TTL_MS = 15e3;
|
|
13075
13082
|
/** Window after a command-driven line write during which the poll stands down. */
|
|
@@ -13106,6 +13113,11 @@ var LifecycleController = class LifecycleController {
|
|
|
13106
13113
|
* a collaboration request can never evict a fired reminder. */
|
|
13107
13114
|
reminderActivity = null;
|
|
13108
13115
|
reminderTimer;
|
|
13116
|
+
/** Single-slot MCP server notice (connect / connecting / disabled). Own slot
|
|
13117
|
+
* for the same reason: a burst of server statuses must never evict a
|
|
13118
|
+
* collaboration request or a fired reminder. */
|
|
13119
|
+
mcpActivity = null;
|
|
13120
|
+
mcpTimer;
|
|
13109
13121
|
/** Sum all four token buckets into the session's total token consumption. */
|
|
13110
13122
|
static sumTokens(usage) {
|
|
13111
13123
|
return usage.inputOther + usage.inputCacheRead + usage.inputCacheCreation + usage.output;
|
|
@@ -13574,7 +13586,8 @@ var LifecycleController = class LifecycleController {
|
|
|
13574
13586
|
labelColor: state.theme.colors.warning,
|
|
13575
13587
|
pulseWave: loader,
|
|
13576
13588
|
reminder: () => this.getReminderActivity(),
|
|
13577
|
-
activity: () => this.getCollabActivity()
|
|
13589
|
+
activity: () => this.getCollabActivity(),
|
|
13590
|
+
notice: () => this.getMcpActivity()
|
|
13578
13591
|
}));
|
|
13579
13592
|
}
|
|
13580
13593
|
break;
|
|
@@ -13587,7 +13600,8 @@ var LifecycleController = class LifecycleController {
|
|
|
13587
13600
|
label: tip === void 0 ? "" : composeTipLabel(t(tip.i18nKey), tip, state.theme.colors.primary),
|
|
13588
13601
|
labelColor: state.theme.colors.textDim,
|
|
13589
13602
|
reminder: () => this.getReminderActivity(),
|
|
13590
|
-
activity: () => this.getCollabActivity()
|
|
13603
|
+
activity: () => this.getCollabActivity(),
|
|
13604
|
+
notice: () => this.getMcpActivity()
|
|
13591
13605
|
}));
|
|
13592
13606
|
if (tip !== void 0) this.startTipRotation();
|
|
13593
13607
|
break;
|
|
@@ -13673,6 +13687,29 @@ var LifecycleController = class LifecycleController {
|
|
|
13673
13687
|
getReminderActivity() {
|
|
13674
13688
|
return this.reminderActivity;
|
|
13675
13689
|
}
|
|
13690
|
+
/**
|
|
13691
|
+
* Shows an MCP server notice on the status row (connected / connecting /
|
|
13692
|
+
* disabled). Single slot, newest wins, expires after `MCP_ACTIVITY_TTL_MS`;
|
|
13693
|
+
* the row reads it live, so no rebuild (and no wave reset) is involved.
|
|
13694
|
+
* The colour is chosen by the caller (success / muted).
|
|
13695
|
+
*/
|
|
13696
|
+
showMcpActivity(text, color) {
|
|
13697
|
+
this.mcpActivity = {
|
|
13698
|
+
text,
|
|
13699
|
+
color
|
|
13700
|
+
};
|
|
13701
|
+
if (this.mcpTimer !== void 0) clearTimeout(this.mcpTimer);
|
|
13702
|
+
this.mcpTimer = setTimeout(() => {
|
|
13703
|
+
this.mcpTimer = void 0;
|
|
13704
|
+
this.mcpActivity = null;
|
|
13705
|
+
this.host.state.ui?.requestRender();
|
|
13706
|
+
}, MCP_ACTIVITY_TTL_MS);
|
|
13707
|
+
this.host.state.ui?.requestRender();
|
|
13708
|
+
}
|
|
13709
|
+
/** Live getter consumed by the status row on every render. */
|
|
13710
|
+
getMcpActivity() {
|
|
13711
|
+
return this.mcpActivity;
|
|
13712
|
+
}
|
|
13676
13713
|
/** Drops every transient chip (session switch, shutdown). */
|
|
13677
13714
|
clearStatusActivity() {
|
|
13678
13715
|
if (this.collabTimer !== void 0) {
|
|
@@ -13685,6 +13722,11 @@ var LifecycleController = class LifecycleController {
|
|
|
13685
13722
|
this.reminderTimer = void 0;
|
|
13686
13723
|
}
|
|
13687
13724
|
this.reminderActivity = null;
|
|
13725
|
+
if (this.mcpTimer !== void 0) {
|
|
13726
|
+
clearTimeout(this.mcpTimer);
|
|
13727
|
+
this.mcpTimer = void 0;
|
|
13728
|
+
}
|
|
13729
|
+
this.mcpActivity = null;
|
|
13688
13730
|
}
|
|
13689
13731
|
/**
|
|
13690
13732
|
* Stops every animation this controller owns. Called from the shutdown path:
|
|
@@ -19872,7 +19914,6 @@ var ScreamTUI = class {
|
|
|
19872
19914
|
clearRuntimeMarker(getDataDir());
|
|
19873
19915
|
await this.closeSession();
|
|
19874
19916
|
await this.harness.close();
|
|
19875
|
-
this.sessionEventHandler.stopAllMcpServerStatusSpinners();
|
|
19876
19917
|
this.state.ui.stop();
|
|
19877
19918
|
if (this.onExit) await this.onExit(exitCode);
|
|
19878
19919
|
}
|
|
@@ -20049,6 +20090,10 @@ var ScreamTUI = class {
|
|
|
20049
20090
|
showReminderActivity(text, tone) {
|
|
20050
20091
|
this.lifecycleController.showReminderActivity(text, tone);
|
|
20051
20092
|
}
|
|
20093
|
+
/** MCP server notice above the editor (connecting / connected / disabled). */
|
|
20094
|
+
showMcpActivity(text, color) {
|
|
20095
|
+
this.lifecycleController.showMcpActivity(text, color);
|
|
20096
|
+
}
|
|
20052
20097
|
/** Drops every transient chip on the status row (session switch). */
|
|
20053
20098
|
clearStatusActivity() {
|
|
20054
20099
|
this.lifecycleController.clearStatusActivity();
|
|
@@ -20202,7 +20247,7 @@ var ScreamTUI = class {
|
|
|
20202
20247
|
const card = new OnboardingCardComponent({
|
|
20203
20248
|
colors: this.state.theme.colors,
|
|
20204
20249
|
onConfigure: () => {
|
|
20205
|
-
import("./dispatch-
|
|
20250
|
+
import("./dispatch-DD8Vu4Qc.mjs").then(({ handleConnectCommand }) => handleConnectCommand(this, "")).finally(() => {
|
|
20206
20251
|
this.restoreEditor();
|
|
20207
20252
|
onDone?.();
|
|
20208
20253
|
});
|
|
@@ -20264,7 +20309,6 @@ var ScreamTUI = class {
|
|
|
20264
20309
|
this.mountEditorReplacement(card);
|
|
20265
20310
|
}
|
|
20266
20311
|
clearTranscriptAndRedraw() {
|
|
20267
|
-
this.sessionEventHandler.stopAllMcpServerStatusSpinners();
|
|
20268
20312
|
clearGoalState();
|
|
20269
20313
|
clearInfoPanelState(this.state);
|
|
20270
20314
|
clearEvalPanelState(this.state);
|
|
@@ -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-
|
|
6
|
+
import { Qt as handleConnectCommand } from "./dispatch-DMntc47e.mjs";
|
|
7
7
|
export { handleConnectCommand };
|