scream-code 0.16.2 → 0.16.4
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/dist/{app-V7s7I7Nr.mjs → app-C0OLgL_b.mjs} +177 -256
- package/dist/{dispatch-BRkUiHzo.mjs → dispatch-C7ujqj4p.mjs} +1 -1
- package/dist/{dispatch-D0mYcf1X.mjs → dispatch-La1sAZPF.mjs} +726 -533
- package/dist/main.mjs +1 -1
- package/dist/{text-input-dialog-CzJKBIoN.mjs → text-input-dialog--J3ngWFv.mjs} +36 -18
- package/dist/{text-input-dialog-Dp2TUSjQ.mjs → text-input-dialog-CNhL-3wm.mjs} +1 -1
- package/package.json +1 -1
|
@@ -4,8 +4,8 @@ import { dirname as __cjsShimDirname } from 'node:path';
|
|
|
4
4
|
const __filename = __cjsShimFileURLToPath(import.meta.url);
|
|
5
5
|
const __dirname = __cjsShimDirname(__filename);
|
|
6
6
|
import "./suppress-sqlite-warning-C2VB0doZ.mjs";
|
|
7
|
-
import { $ as
|
|
8
|
-
import { a as setLocale, i as getLocale, o as t } from "./text-input-dialog
|
|
7
|
+
import { $n as readSessionIndex, $t as SubagentSlots, A as langFromPath, An as startManualEmbeddingDownload, At as toggleEmptySessionHint, B as charsForTokenBudget, Bn as getLogDir, Bt as OSC11_QUERY, C as getDaemonInstructions, Cn as buildSkillSlashCommands, D as renderDiffLines, Dn as setExperimentalFlags, Dt as createMarkdownTheme, E as ToolCallComponent, En as isExperimentalFlagEnabled, Et as createEditorTheme, F as replaceTabs, Fn as loadTuiConfig, Ft as parseOsc11BackgroundTheme, G as WelcomeComponent, Gn as PRODUCT_NAME, Gt as TERMINAL_FOCUS_IN, H as getSharedSpeedTracker, Hn as CLI_COMMAND_NAME, Ht as OSC11_RESPONSE_PREFIX, I as sanitizeShellOutput, In as saveTuiConfig, It as DISABLE_TERMINAL_FOCUS_REPORTING, J as resetBreathingClock, Jn as saveCatalogCache, Jt as TERMINAL_THEME_LIGHT, K as BREATHE_CYCLE_MS, Kn as DEFAULT_CATALOG_URL, Kt as TERMINAL_FOCUS_OUT, L as SkillActivationComponent, Ln as detectShellEnvironment, Lt as DISABLE_TERMINAL_THEME_REPORTING, M as ThinkingComponent, Mn as PULSE_WAVE_FRAMES, Mt as contrastTextHex, N as NoticeMessageComponent, Nn as TuiConfigParseError, Nt as getColorPalette, O as renderDiffLinesClustered, On as getKnowledgeStore, Ot as isEmptySessionHintDismissed, P as StatusMessageComponent, Pn as TuiLikePreferencesSchema, Pt as detectTerminalTheme, Qn as appendSessionIndexEntry, Qt as lerpGradient, R as AssistantMessageComponent, Rn as getDataDir, Rt as ENABLE_TERMINAL_FOCUS_REPORTING, Sn as getNoActiveSessionMessage, St as clearInfoPanelState, T as UserMessageComponent, Tn as sortSlashCommands, Tt as resolveThemeSync, U as BackgroundAgentStatusComponent, Un as CLI_UI_MODE, Ut as OSC11_RESPONSE_PREFIX_NO_ESC, V as estimateTokens, Vn as detectInstallSource, Vt as OSC11_RESPONSE, W as AgentGroupComponent, Wn as CLI_USER_AGENT_PRODUCT, Wt as QUERY_TERMINAL_THEME, X as clearGoalState, Xn as encodeWorkDirKey, Xt as isStreaming, Y as CompactionComponent, Yn as ScreamHarness, Yt as isBusy, Z as refineGoal, Zn as normalizeWorkDir, Zt as FooterComponent, _ as selectUpdateTarget, _n as SESSION_TIPS, an as STATUS_BULLET, ar as log, at as changeThinkingLevel, b as appendJsonlLine, bn as getCtrlDHint, bt as refreshProviderBalance, c as hasDispose, cn as formatErrorMessage, cr as isOrphanedToolCallError, d as MoonLoader, dn as serializeToolResultOutput, dt as handleFusionPlanCommand, er as removeSessionIndexEntry, f as formatMemoryMemoForInjection, fn as stringValue, gn as MAIN_AGENT_ID, hn as EXIT_CONFIRM_WINDOW_MS, i as buildRoleAdditionalText, in as printableChar, ir as flushDiagnosticLogs, it as toTerminalHyperlink, j as CachedContainer, jn as PIXEL_PULSE_FRAMES, jt as createThemeStyles, k as highlightLines, kn as isEmbeddingModelCached, kt as isTurnElapsedEnabled, l as isExpandable, ln as isTodoItemShape, lr as ErrorCodes, mn as EMPTY_SESSION_HINT_URL, n as clearEvalPanelState, nr as resolveScreamHome, on as appendStreamingArgsPreview, or as resolveGlobalLogPath, ot as getModelCycleLevel, pn as truncateErrorMessage, pt as handlePlanCommand, q as getBreathingFrame, qn as fetchCatalog, qt as TERMINAL_THEME_DARK, r as openUrl, rr as MemoryMemoStore, rt as isInternalMessage, s as disposeChildren, sn as argsRecord, sr as isScreamError, t as dispatchInput, u as isPlanExpandable, un as parseStreamingArgs, ur as SCREAM_ERROR_INFO, v as refreshUpdateCache, vn as TIP_ROTATION_INTERVAL_MS, wn as BUILTIN_SLASH_COMMANDS, x as readJsonlFile, xn as getLlmNotSetMessage, xt as supportsBalance, y as readUpdateCache, yn as getCtrlCHint, z as ActivityGroupComponent, zn as getInputHistoryFile, zt as ENABLE_TERMINAL_THEME_REPORTING } from "./dispatch-La1sAZPF.mjs";
|
|
8
|
+
import { a as setLocale, i as getLocale, o as t } from "./text-input-dialog--J3ngWFv.mjs";
|
|
9
9
|
import { createRequire } from "node:module";
|
|
10
10
|
import { randomBytes, randomUUID, scryptSync, timingSafeEqual } from "node:crypto";
|
|
11
11
|
import { access, appendFile, chmod, mkdir, mkdtemp, readFile, readdir, realpath, rename, rm, stat, unlink, writeFile } from "node:fs/promises";
|
|
@@ -32,7 +32,7 @@ function optionalBuildString(value) {
|
|
|
32
32
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
33
33
|
}
|
|
34
34
|
const SCREAM_BUILD_INFO = {
|
|
35
|
-
version: optionalBuildString("0.16.
|
|
35
|
+
version: optionalBuildString("0.16.4"),
|
|
36
36
|
channel: optionalBuildString(""),
|
|
37
37
|
commit: optionalBuildString(""),
|
|
38
38
|
buildTarget: optionalBuildString("darwin-arm64")
|
|
@@ -4353,28 +4353,25 @@ var StreamingUIController = class StreamingUIController {
|
|
|
4353
4353
|
_activeToolCalls = /* @__PURE__ */ new Map();
|
|
4354
4354
|
_streamingToolCallArguments = /* @__PURE__ */ new Map();
|
|
4355
4355
|
_pendingToolComponents = /* @__PURE__ */ new Map();
|
|
4356
|
-
_pendingReadGroupComponents = /* @__PURE__ */ new Map();
|
|
4357
4356
|
_pendingAgentGroup = null;
|
|
4358
|
-
_pendingReadGroup = null;
|
|
4359
4357
|
_activityGroup;
|
|
4360
4358
|
/** Guards the single `registerLiveComponent` call for the turn's block. */
|
|
4361
4359
|
_activityGroupRegistered = false;
|
|
4362
4360
|
/** Block that borrowed a card, so late results refresh their own block. */
|
|
4363
4361
|
_groupByToolCard = /* @__PURE__ */ new WeakMap();
|
|
4364
|
-
/** Reasoning of the turn's earlier steps, kept when a step's draft resets. */
|
|
4365
|
-
_turnThinkingHistory = "";
|
|
4366
|
-
_lastThinkingText = "";
|
|
4367
4362
|
/**
|
|
4368
4363
|
* Tools that keep their own transcript card instead of joining the turn's
|
|
4369
4364
|
* activity block:
|
|
4370
|
-
* - `
|
|
4371
|
-
*
|
|
4365
|
+
* - `Agent` is owned by the agent group machinery (and by `/revoke`, which
|
|
4366
|
+
* walks those groups);
|
|
4372
4367
|
* - `AskUserQuestion` returns early above and mounts its finished card;
|
|
4373
4368
|
* - `ExitPlanMode` owns the plan box, which Ctrl+E expands by walking the
|
|
4374
4369
|
* transcript container's direct children.
|
|
4370
|
+
*
|
|
4371
|
+
* Every other tool is a row inside the block, so a turn reads as one
|
|
4372
|
+
* timeline instead of a mix of cards and groups.
|
|
4375
4373
|
*/
|
|
4376
4374
|
static STANDALONE_TOOL_NAMES = new Set([
|
|
4377
|
-
"Read",
|
|
4378
4375
|
"Agent",
|
|
4379
4376
|
"AskUserQuestion",
|
|
4380
4377
|
"ExitPlanMode",
|
|
@@ -4460,9 +4457,6 @@ var StreamingUIController = class StreamingUIController {
|
|
|
4460
4457
|
hasPendingAgentGroup() {
|
|
4461
4458
|
return this._pendingAgentGroup !== null;
|
|
4462
4459
|
}
|
|
4463
|
-
hasPendingReadGroup() {
|
|
4464
|
-
return this._pendingReadGroup !== null;
|
|
4465
|
-
}
|
|
4466
4460
|
removeToolComponentIfInactive(toolCallId) {
|
|
4467
4461
|
if (!this._activeToolCalls.has(toolCallId)) this._pendingToolComponents.delete(toolCallId);
|
|
4468
4462
|
}
|
|
@@ -4596,8 +4590,6 @@ var StreamingUIController = class StreamingUIController {
|
|
|
4596
4590
|
this._activeToolCalls.clear();
|
|
4597
4591
|
for (const toolCallId of completedToolCallIds) this._pendingToolComponents.delete(toolCallId);
|
|
4598
4592
|
this._pendingAgentGroup = null;
|
|
4599
|
-
this._pendingReadGroup = null;
|
|
4600
|
-
this._pendingReadGroupComponents.clear();
|
|
4601
4593
|
this._currentTurnId = void 0;
|
|
4602
4594
|
this._currentStep = 0;
|
|
4603
4595
|
this._streamingToolCallArguments.clear();
|
|
@@ -4618,8 +4610,8 @@ var StreamingUIController = class StreamingUIController {
|
|
|
4618
4610
|
const { state } = this.host;
|
|
4619
4611
|
const group = new ActivityGroupComponent(state.theme.colors, state.ui);
|
|
4620
4612
|
group.setRunning(state.appState.streamingPhase !== "idle");
|
|
4613
|
+
group.setExpanded(state.toolOutputExpanded);
|
|
4621
4614
|
this._activityGroup = group;
|
|
4622
|
-
this._turnThinkingHistory = "";
|
|
4623
4615
|
state.transcriptContainer.addChild(group);
|
|
4624
4616
|
state.ui.requestRender();
|
|
4625
4617
|
return group;
|
|
@@ -4650,12 +4642,22 @@ var StreamingUIController = class StreamingUIController {
|
|
|
4650
4642
|
* releases the reference so the next turn opens a fresh one. Blocks with
|
|
4651
4643
|
* content stay mounted (replayed history keeps its blocks).
|
|
4652
4644
|
*/
|
|
4645
|
+
/**
|
|
4646
|
+
* Files a background task notice (started / completed / failed) as a step of
|
|
4647
|
+
* the turn that spawned it. Returns false when no block is open — a background
|
|
4648
|
+
* task that outlives its turn keeps its own row instead of reopening a settled
|
|
4649
|
+
* block — so the caller can fall back to mounting it on its own.
|
|
4650
|
+
*/
|
|
4651
|
+
attachNotice(data) {
|
|
4652
|
+
const group = this._activityGroup;
|
|
4653
|
+
if (group === void 0) return false;
|
|
4654
|
+
group.attachNotice(data);
|
|
4655
|
+
return true;
|
|
4656
|
+
}
|
|
4653
4657
|
endActivityGroup() {
|
|
4654
4658
|
const group = this._activityGroup;
|
|
4655
4659
|
this._activityGroup = void 0;
|
|
4656
4660
|
this._activityGroupRegistered = false;
|
|
4657
|
-
this._turnThinkingHistory = "";
|
|
4658
|
-
this._lastThinkingText = "";
|
|
4659
4661
|
if (group === void 0) return;
|
|
4660
4662
|
group.setRunning(false);
|
|
4661
4663
|
if (group.isEmpty()) {
|
|
@@ -4667,11 +4669,6 @@ var StreamingUIController = class StreamingUIController {
|
|
|
4667
4669
|
this.host.transcriptController.unmarkPending(group);
|
|
4668
4670
|
group.dispose();
|
|
4669
4671
|
}
|
|
4670
|
-
/** Reasoning text of the whole turn: earlier steps plus the current draft. */
|
|
4671
|
-
activityThinkingText(draft) {
|
|
4672
|
-
if (this._turnThinkingHistory.length === 0) return draft;
|
|
4673
|
-
return `${this._turnThinkingHistory}\n${draft}`;
|
|
4674
|
-
}
|
|
4675
4672
|
disposeActiveThinkingComponent() {
|
|
4676
4673
|
if (this._activeThinkingComponent !== void 0) {
|
|
4677
4674
|
this._activeThinkingComponent.dispose();
|
|
@@ -4791,7 +4788,6 @@ var StreamingUIController = class StreamingUIController {
|
|
|
4791
4788
|
this._streamingToolCallArguments.clear();
|
|
4792
4789
|
this.disposeAndClearPendingToolComponents();
|
|
4793
4790
|
this._pendingAgentGroup = null;
|
|
4794
|
-
this._pendingReadGroup = null;
|
|
4795
4791
|
}
|
|
4796
4792
|
resetToolCallState() {
|
|
4797
4793
|
this._activeToolCalls.clear();
|
|
@@ -4860,7 +4856,6 @@ var StreamingUIController = class StreamingUIController {
|
|
|
4860
4856
|
onStreamingTextStart() {
|
|
4861
4857
|
const { state } = this.host;
|
|
4862
4858
|
this._pendingAgentGroup = null;
|
|
4863
|
-
this._pendingReadGroup = null;
|
|
4864
4859
|
const entry = {
|
|
4865
4860
|
id: nextTranscriptId(),
|
|
4866
4861
|
kind: "assistant",
|
|
@@ -4901,7 +4896,6 @@ var StreamingUIController = class StreamingUIController {
|
|
|
4901
4896
|
const { state } = this.host;
|
|
4902
4897
|
if (this._activeThinkingComponent === void 0) {
|
|
4903
4898
|
this._pendingAgentGroup = null;
|
|
4904
|
-
this._pendingReadGroup = null;
|
|
4905
4899
|
const component = new ThinkingComponent(fullText, state.theme.colors, true, "finalized", state.ui);
|
|
4906
4900
|
const entry = {
|
|
4907
4901
|
id: nextTranscriptId(),
|
|
@@ -4917,13 +4911,11 @@ var StreamingUIController = class StreamingUIController {
|
|
|
4917
4911
|
this.host.transcriptController.markPending(component);
|
|
4918
4912
|
const group = this.ensureActivityGroup();
|
|
4919
4913
|
this.registerActivityGroupEntry(group, entry);
|
|
4920
|
-
|
|
4921
|
-
group.setThinking(this.activityThinkingText(fullText), true);
|
|
4914
|
+
group.appendThinking(fullText, true);
|
|
4922
4915
|
} else {
|
|
4923
4916
|
this._activeThinkingComponent.setText(fullText);
|
|
4924
4917
|
if (this._thinkingEntry !== void 0) this._thinkingEntry.content = fullText;
|
|
4925
|
-
this.
|
|
4926
|
-
this.ensureActivityGroup().setThinking(this.activityThinkingText(fullText), true);
|
|
4918
|
+
this.ensureActivityGroup().appendThinking(fullText, true);
|
|
4927
4919
|
}
|
|
4928
4920
|
state.ui.requestRender();
|
|
4929
4921
|
}
|
|
@@ -4936,17 +4928,11 @@ var StreamingUIController = class StreamingUIController {
|
|
|
4936
4928
|
this.host.transcriptController.releaseLiveComponent(component);
|
|
4937
4929
|
this._activeThinkingComponent = void 0;
|
|
4938
4930
|
this._thinkingEntry = void 0;
|
|
4939
|
-
if (this._lastThinkingText.trim().length > 0) this._turnThinkingHistory = this.activityThinkingText(this._lastThinkingText);
|
|
4940
|
-
this._lastThinkingText = "";
|
|
4941
4931
|
this._activityGroup?.endThinking();
|
|
4942
4932
|
this.host.state.ui.requestRender();
|
|
4943
4933
|
}
|
|
4944
4934
|
onToolCallStart(toolCall) {
|
|
4945
4935
|
if (toolCall.name === "AskUserQuestion") return;
|
|
4946
|
-
if (toolCall.name === "ReadGroup") {
|
|
4947
|
-
this.startReadGroupToolCall(toolCall);
|
|
4948
|
-
return;
|
|
4949
|
-
}
|
|
4950
4936
|
const { state } = this.host;
|
|
4951
4937
|
const tc = new ToolCallComponent(toolCall, void 0, state.theme.colors, state.ui, state.theme.markdownTheme, state.appState.workDir);
|
|
4952
4938
|
tc.setPermissionMode(state.appState.permissionMode);
|
|
@@ -4964,10 +4950,8 @@ var StreamingUIController = class StreamingUIController {
|
|
|
4964
4950
|
this.host.transcriptController.markPending(tc);
|
|
4965
4951
|
if (state.planExpanded) tc.setPlanExpanded(true);
|
|
4966
4952
|
if (toolCall.name !== "Agent") this._pendingAgentGroup = null;
|
|
4967
|
-
if (toolCall
|
|
4968
|
-
|
|
4969
|
-
if (!handled) handled = this.tryAttachReadToolCall(toolCall, tc);
|
|
4970
|
-
if (!handled) if (StreamingUIController.STANDALONE_TOOL_NAMES.has(toolCall.name)) {
|
|
4953
|
+
if (!this.tryAttachAgentToolCall(toolCall, tc)) if (StreamingUIController.STANDALONE_TOOL_NAMES.has(toolCall.name)) {
|
|
4954
|
+
tc.setExpanded(state.toolOutputExpanded);
|
|
4971
4955
|
state.transcriptContainer.addChild(tc);
|
|
4972
4956
|
state.ui.requestRender();
|
|
4973
4957
|
} else {
|
|
@@ -4992,39 +4976,8 @@ var StreamingUIController = class StreamingUIController {
|
|
|
4992
4976
|
})();
|
|
4993
4977
|
}
|
|
4994
4978
|
}
|
|
4995
|
-
startReadGroupToolCall(toolCall) {
|
|
4996
|
-
const { state, transcriptController } = this.host;
|
|
4997
|
-
const rgc = new ReadGroupComponent(state.theme.colors, state.ui);
|
|
4998
|
-
const entry = {
|
|
4999
|
-
id: nextTranscriptId(),
|
|
5000
|
-
kind: "tool_call",
|
|
5001
|
-
turnId: toolCall.turnId ?? this._currentTurnId,
|
|
5002
|
-
renderMode: "plain",
|
|
5003
|
-
content: toolCall.name,
|
|
5004
|
-
toolCallData: toolCall
|
|
5005
|
-
};
|
|
5006
|
-
this._pendingReadGroupComponents.set(toolCall.id, rgc);
|
|
5007
|
-
this._pendingReadGroup = null;
|
|
5008
|
-
this._pendingAgentGroup = null;
|
|
5009
|
-
this.host.pushTranscriptEntry(entry);
|
|
5010
|
-
transcriptController.registerLiveComponent(rgc, entry);
|
|
5011
|
-
transcriptController.markPending(rgc);
|
|
5012
|
-
state.transcriptContainer.addChild(rgc);
|
|
5013
|
-
state.ui.requestRender();
|
|
5014
|
-
}
|
|
5015
4979
|
onToolCallEnd(toolCallId, result) {
|
|
5016
4980
|
const { state } = this.host;
|
|
5017
|
-
const rgc = this._pendingReadGroupComponents.get(toolCallId);
|
|
5018
|
-
if (rgc !== void 0) {
|
|
5019
|
-
rgc.setResults(parseReadGroupOutput(result.output));
|
|
5020
|
-
this.host.transcriptController.unmarkPending(rgc);
|
|
5021
|
-
this._pendingReadGroupComponents.delete(toolCallId);
|
|
5022
|
-
const entry = this.host.state.transcriptEntries.find((e) => e.toolCallData?.id === toolCallId);
|
|
5023
|
-
if (entry?.toolCallData !== void 0) entry.toolCallData.result = result;
|
|
5024
|
-
this.host.transcriptController.commit();
|
|
5025
|
-
state.ui.requestRender();
|
|
5026
|
-
return;
|
|
5027
|
-
}
|
|
5028
4981
|
const matchedCall = this._activeToolCalls.get(toolCallId);
|
|
5029
4982
|
const tc = this._pendingToolComponents.get(toolCallId);
|
|
5030
4983
|
if (tc) {
|
|
@@ -5044,6 +4997,7 @@ var StreamingUIController = class StreamingUIController {
|
|
|
5044
4997
|
if (matchedCall?.name === "AskUserQuestion") {
|
|
5045
4998
|
const completed = new ToolCallComponent(matchedCall, result, state.theme.colors, state.ui, state.theme.markdownTheme, state.appState.workDir);
|
|
5046
4999
|
completed.setPermissionMode(state.appState.permissionMode);
|
|
5000
|
+
completed.setExpanded(state.toolOutputExpanded);
|
|
5047
5001
|
if (state.planExpanded) completed.setPlanExpanded(true);
|
|
5048
5002
|
const entry = {
|
|
5049
5003
|
id: nextTranscriptId(),
|
|
@@ -5152,6 +5106,7 @@ var StreamingUIController = class StreamingUIController {
|
|
|
5152
5106
|
turnId,
|
|
5153
5107
|
solo: tc
|
|
5154
5108
|
};
|
|
5109
|
+
tc.setExpanded(state.toolOutputExpanded);
|
|
5155
5110
|
state.transcriptContainer.addChild(tc);
|
|
5156
5111
|
state.ui.requestRender();
|
|
5157
5112
|
return true;
|
|
@@ -5198,69 +5153,6 @@ var StreamingUIController = class StreamingUIController {
|
|
|
5198
5153
|
}
|
|
5199
5154
|
return group;
|
|
5200
5155
|
}
|
|
5201
|
-
tryAttachReadToolCall(toolCall, tc) {
|
|
5202
|
-
const { state } = this.host;
|
|
5203
|
-
if (toolCall.name !== "Read") {
|
|
5204
|
-
this._pendingReadGroup = null;
|
|
5205
|
-
return false;
|
|
5206
|
-
}
|
|
5207
|
-
const step = toolCall.step ?? this._currentStep;
|
|
5208
|
-
const turnId = toolCall.turnId ?? this._currentTurnId;
|
|
5209
|
-
const pending = this._pendingReadGroup;
|
|
5210
|
-
if (pending !== null && (pending.step !== step || pending.turnId !== turnId)) this._pendingReadGroup = null;
|
|
5211
|
-
const cur = this._pendingReadGroup;
|
|
5212
|
-
if (cur === null) {
|
|
5213
|
-
this._pendingReadGroup = {
|
|
5214
|
-
step,
|
|
5215
|
-
turnId,
|
|
5216
|
-
solo: tc
|
|
5217
|
-
};
|
|
5218
|
-
state.transcriptContainer.addChild(tc);
|
|
5219
|
-
state.ui.requestRender();
|
|
5220
|
-
return true;
|
|
5221
|
-
}
|
|
5222
|
-
if (cur.group !== void 0) {
|
|
5223
|
-
cur.group.attach(toolCall.id, tc);
|
|
5224
|
-
return true;
|
|
5225
|
-
}
|
|
5226
|
-
const solo = cur.solo;
|
|
5227
|
-
if (solo === void 0) {
|
|
5228
|
-
this._pendingReadGroup = {
|
|
5229
|
-
step,
|
|
5230
|
-
turnId,
|
|
5231
|
-
solo: tc
|
|
5232
|
-
};
|
|
5233
|
-
state.transcriptContainer.addChild(tc);
|
|
5234
|
-
state.ui.requestRender();
|
|
5235
|
-
return true;
|
|
5236
|
-
}
|
|
5237
|
-
const group = this.upgradeSoloReadToGroup(solo);
|
|
5238
|
-
group.attach(toolCall.id, tc);
|
|
5239
|
-
this._pendingReadGroup = {
|
|
5240
|
-
step,
|
|
5241
|
-
turnId,
|
|
5242
|
-
group
|
|
5243
|
-
};
|
|
5244
|
-
state.ui.requestRender();
|
|
5245
|
-
return true;
|
|
5246
|
-
}
|
|
5247
|
-
upgradeSoloReadToGroup(solo) {
|
|
5248
|
-
const { state, transcriptController } = this.host;
|
|
5249
|
-
const group = new ReadGroupComponent(state.theme.colors, state.ui);
|
|
5250
|
-
const children = state.transcriptContainer.children;
|
|
5251
|
-
const idx = children.indexOf(solo);
|
|
5252
|
-
if (idx >= 0) {
|
|
5253
|
-
children[idx] = group;
|
|
5254
|
-
state.transcriptContainer.invalidate();
|
|
5255
|
-
} else state.transcriptContainer.addChild(group);
|
|
5256
|
-
group.attach(solo.toolCallView.id, solo);
|
|
5257
|
-
const entry = transcriptController.findEntryForComponent(solo);
|
|
5258
|
-
if (entry !== void 0) {
|
|
5259
|
-
transcriptController.registerLiveComponent(group, entry);
|
|
5260
|
-
transcriptController.unmarkPending(solo);
|
|
5261
|
-
}
|
|
5262
|
-
return group;
|
|
5263
|
-
}
|
|
5264
5156
|
};
|
|
5265
5157
|
//#endregion
|
|
5266
5158
|
//#region src/tui/components/dialogs/task-output-viewer.ts
|
|
@@ -6472,11 +6364,7 @@ var TranscriptController = class TranscriptController {
|
|
|
6472
6364
|
}
|
|
6473
6365
|
case "thinking": return new ThinkingComponent(entry.content, state.theme.colors, true);
|
|
6474
6366
|
case "tool_call":
|
|
6475
|
-
|
|
6476
|
-
const rgc = new ReadGroupComponent(state.theme.colors, state.ui);
|
|
6477
|
-
rgc.setResults(parseReadGroupOutput(entry.toolCallData.result.output));
|
|
6478
|
-
return rgc;
|
|
6479
|
-
}
|
|
6367
|
+
case "tool_result":
|
|
6480
6368
|
if (entry.toolCallData) {
|
|
6481
6369
|
const tc = new ToolCallComponent(entry.toolCallData, entry.toolCallData.result, state.theme.colors, state.ui, state.theme.markdownTheme, state.appState.workDir);
|
|
6482
6370
|
if (state.planExpanded) tc.setPlanExpanded(true);
|
|
@@ -6499,7 +6387,9 @@ var TranscriptController = class TranscriptController {
|
|
|
6499
6387
|
const component = this.createComponent(entry);
|
|
6500
6388
|
if (component) {
|
|
6501
6389
|
this.liveComponentToEntry.set(component, entry);
|
|
6502
|
-
|
|
6390
|
+
const status = entry.backgroundAgentStatus;
|
|
6391
|
+
if (status !== void 0 && this.host.streamingUI.attachNotice(status)) this.releaseLiveComponent(component);
|
|
6392
|
+
else this.host.state.transcriptContainer.addChild(component);
|
|
6503
6393
|
this.host.state.ui.requestRender();
|
|
6504
6394
|
}
|
|
6505
6395
|
return component ?? null;
|
|
@@ -6572,6 +6462,7 @@ var TranscriptController = class TranscriptController {
|
|
|
6572
6462
|
this.committedComponent = void 0;
|
|
6573
6463
|
this.liveComponentToEntry.clear();
|
|
6574
6464
|
this.pendingComponents.clear();
|
|
6465
|
+
state.toolOutputExpanded = false;
|
|
6575
6466
|
disposeChildren(state.transcriptContainer);
|
|
6576
6467
|
this.clearTerminalInlineImages();
|
|
6577
6468
|
state.todoPanel.clear();
|
|
@@ -6619,19 +6510,15 @@ var TranscriptController = class TranscriptController {
|
|
|
6619
6510
|
}
|
|
6620
6511
|
toggleToolOutputExpansion() {
|
|
6621
6512
|
const { state } = this.host;
|
|
6513
|
+
const next = !state.toolOutputExpanded;
|
|
6622
6514
|
const children = state.transcriptContainer.children;
|
|
6623
6515
|
for (let i = children.length - 1; i >= 0; i -= 1) {
|
|
6624
6516
|
const child = children[i];
|
|
6625
6517
|
if (child === void 0) continue;
|
|
6626
|
-
if (
|
|
6627
|
-
|
|
6628
|
-
child.setExpanded(state.toolOutputExpanded);
|
|
6629
|
-
state.ui.requestRender();
|
|
6630
|
-
return;
|
|
6631
|
-
}
|
|
6632
|
-
if (child instanceof ReadGroupComponent || child instanceof AgentGroupComponent) break;
|
|
6518
|
+
if (child instanceof UserMessageComponent || child instanceof SkillActivationComponent || child instanceof CronMessageComponent || child instanceof CommittedTranscriptComponent) break;
|
|
6519
|
+
if (isExpandable(child)) child.setExpanded(next);
|
|
6633
6520
|
}
|
|
6634
|
-
state.toolOutputExpanded =
|
|
6521
|
+
state.toolOutputExpanded = next;
|
|
6635
6522
|
state.ui.requestRender();
|
|
6636
6523
|
}
|
|
6637
6524
|
togglePlanExpansion() {
|
|
@@ -8286,6 +8173,7 @@ var LifecycleController = class LifecycleController {
|
|
|
8286
8173
|
case "waiting":
|
|
8287
8174
|
case "composing":
|
|
8288
8175
|
case "tool":
|
|
8176
|
+
case "thinking":
|
|
8289
8177
|
{
|
|
8290
8178
|
const loader = new PulseWaveLoader(state.ui, state.theme.colors.primary);
|
|
8291
8179
|
this.statusBarLoader = loader;
|
|
@@ -8296,7 +8184,6 @@ var LifecycleController = class LifecycleController {
|
|
|
8296
8184
|
}));
|
|
8297
8185
|
}
|
|
8298
8186
|
break;
|
|
8299
|
-
case "thinking": break;
|
|
8300
8187
|
case "idle":
|
|
8301
8188
|
case "hidden":
|
|
8302
8189
|
if (mode === "idle" && state.transcriptEntries.length === 0 && !isEmptySessionHintDismissed()) {
|
|
@@ -13995,7 +13882,7 @@ var ScreamTUI = class {
|
|
|
13995
13882
|
const card = new OnboardingCardComponent({
|
|
13996
13883
|
colors: this.state.theme.colors,
|
|
13997
13884
|
onConfigure: () => {
|
|
13998
|
-
import("./dispatch-
|
|
13885
|
+
import("./dispatch-C7ujqj4p.mjs").then(({ handleConnectCommand }) => handleConnectCommand(this, "")).finally(() => {
|
|
13999
13886
|
this.restoreEditor();
|
|
14000
13887
|
onDone?.();
|
|
14001
13888
|
});
|
|
@@ -18456,6 +18343,143 @@ var SessionManager = class {
|
|
|
18456
18343
|
}
|
|
18457
18344
|
};
|
|
18458
18345
|
/**
|
|
18346
|
+
* Session-backed data routes: snapshot, message history / thinking entries,
|
|
18347
|
+
* git status and single-file diff, plus the read-only file gate. Returns true
|
|
18348
|
+
* when the request was handled (including the not-found arms).
|
|
18349
|
+
*/
|
|
18350
|
+
async function handleSessionDataRoutes(req, res, url, method, resolveSession, workDir, fileGate) {
|
|
18351
|
+
const snapshotMatch = new RegExp(`^${API_PREFIX}/sessions/([^/]+)/snapshot(\\?|$)`).exec(url);
|
|
18352
|
+
if (snapshotMatch && method === "GET") {
|
|
18353
|
+
let sessionId;
|
|
18354
|
+
try {
|
|
18355
|
+
sessionId = decodeURIComponent(snapshotMatch[1]);
|
|
18356
|
+
} catch {
|
|
18357
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
18358
|
+
res.end(JSON.stringify({
|
|
18359
|
+
code: 404,
|
|
18360
|
+
message: "Session not found"
|
|
18361
|
+
}));
|
|
18362
|
+
return true;
|
|
18363
|
+
}
|
|
18364
|
+
const ws = resolveSession(sessionId);
|
|
18365
|
+
if (!ws) {
|
|
18366
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
18367
|
+
res.end(JSON.stringify({
|
|
18368
|
+
code: 404,
|
|
18369
|
+
message: "Session not found"
|
|
18370
|
+
}));
|
|
18371
|
+
return true;
|
|
18372
|
+
}
|
|
18373
|
+
try {
|
|
18374
|
+
await ws.ready;
|
|
18375
|
+
const query = new URLSearchParams(url.split("?")[1] ?? "");
|
|
18376
|
+
const tail = Number(query.get("tail") ?? "");
|
|
18377
|
+
sendJson(res, 200, Number.isFinite(tail) && tail > 0 ? ws.getSnapshot({ tail }) : ws.getSnapshot());
|
|
18378
|
+
} catch (error) {
|
|
18379
|
+
sendHttpError(res, error);
|
|
18380
|
+
}
|
|
18381
|
+
return true;
|
|
18382
|
+
}
|
|
18383
|
+
const olderMatch = new RegExp(`^${API_PREFIX}/sessions/([^/?]+)/messages(\\?|$)`).exec(url);
|
|
18384
|
+
if (olderMatch && method === "GET") {
|
|
18385
|
+
let sessionId;
|
|
18386
|
+
try {
|
|
18387
|
+
sessionId = decodeURIComponent(olderMatch[1]);
|
|
18388
|
+
} catch {
|
|
18389
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
18390
|
+
res.end(JSON.stringify({
|
|
18391
|
+
code: 404,
|
|
18392
|
+
message: "Session not found"
|
|
18393
|
+
}));
|
|
18394
|
+
return true;
|
|
18395
|
+
}
|
|
18396
|
+
const ws = resolveSession(sessionId);
|
|
18397
|
+
if (!ws) {
|
|
18398
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
18399
|
+
res.end(JSON.stringify({
|
|
18400
|
+
code: 404,
|
|
18401
|
+
message: "Session not found"
|
|
18402
|
+
}));
|
|
18403
|
+
return true;
|
|
18404
|
+
}
|
|
18405
|
+
try {
|
|
18406
|
+
await ws.ready;
|
|
18407
|
+
const query = new URLSearchParams(url.split("?")[1] ?? "");
|
|
18408
|
+
const seq = Number(query.get("seq") ?? "0");
|
|
18409
|
+
const tool = query.get("tool") ?? "";
|
|
18410
|
+
if (Number.isFinite(seq) && seq > 0 && tool) {
|
|
18411
|
+
sendJson(res, 200, { output: ws.getThinkingEntry(seq, tool) });
|
|
18412
|
+
return true;
|
|
18413
|
+
}
|
|
18414
|
+
const before = Number(query.get("before") ?? "0");
|
|
18415
|
+
const tail = Number(query.get("tail") ?? "50");
|
|
18416
|
+
sendJson(res, 200, Number.isFinite(before) && before > 0 ? ws.getMessagesOlder(before, Number.isFinite(tail) && tail > 0 ? tail : 50) : {
|
|
18417
|
+
messages: [],
|
|
18418
|
+
hasMore: false
|
|
18419
|
+
});
|
|
18420
|
+
} catch (error) {
|
|
18421
|
+
sendHttpError(res, error);
|
|
18422
|
+
}
|
|
18423
|
+
return true;
|
|
18424
|
+
}
|
|
18425
|
+
if (url === `${API_PREFIX}/git/status` && method === "GET") {
|
|
18426
|
+
const gs = await getGitStatus(workDir);
|
|
18427
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
18428
|
+
res.end(JSON.stringify(gs));
|
|
18429
|
+
return true;
|
|
18430
|
+
}
|
|
18431
|
+
if (url.startsWith(`${API_PREFIX}/git/diff?`) && method === "GET") {
|
|
18432
|
+
const relPath = new URLSearchParams(url.split("?")[1] ?? "").get("path") ?? "";
|
|
18433
|
+
try {
|
|
18434
|
+
const result = await getGitFileDiff(workDir, relPath);
|
|
18435
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
18436
|
+
res.end(JSON.stringify({
|
|
18437
|
+
path: relPath,
|
|
18438
|
+
patch: result?.patch ?? ""
|
|
18439
|
+
}));
|
|
18440
|
+
} catch (error) {
|
|
18441
|
+
sendHttpError(res, error);
|
|
18442
|
+
}
|
|
18443
|
+
return true;
|
|
18444
|
+
}
|
|
18445
|
+
if (await handleFilesRoutes(req, res, url, method, API_PREFIX, fileGate)) return true;
|
|
18446
|
+
return false;
|
|
18447
|
+
}
|
|
18448
|
+
/**
|
|
18449
|
+
* SPA shell (`no-store`, so a reload never serves a stale bundle), content-
|
|
18450
|
+
* hashed `/assets/` with long-term caching, and the terminal 404. Always ends
|
|
18451
|
+
* the request, so it must be the last handler in the chain.
|
|
18452
|
+
*/
|
|
18453
|
+
async function handleStaticRoutes(res, url, publicDir) {
|
|
18454
|
+
if (url === "/" || url === "/index.html") {
|
|
18455
|
+
try {
|
|
18456
|
+
const html = await readFile(join(publicDir, "index.html"), "utf-8");
|
|
18457
|
+
res.writeHead(200, {
|
|
18458
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
18459
|
+
"Cache-Control": "no-store"
|
|
18460
|
+
});
|
|
18461
|
+
res.end(html);
|
|
18462
|
+
} catch {
|
|
18463
|
+
res.writeHead(500, { "Content-Type": "text/plain" });
|
|
18464
|
+
res.end("Failed to load web UI. Did you run pnpm web:build?");
|
|
18465
|
+
}
|
|
18466
|
+
return;
|
|
18467
|
+
}
|
|
18468
|
+
const safeUrl = url.replaceAll(/\?.*$/g, "").replaceAll(/\.{2,}/g, "");
|
|
18469
|
+
try {
|
|
18470
|
+
const filePath = join(publicDir, safeUrl);
|
|
18471
|
+
const contentType = contentTypes[filePath.split(".").pop() ?? ""] ?? "application/octet-stream";
|
|
18472
|
+
const data = await readFile(filePath);
|
|
18473
|
+
const headers = { "Content-Type": contentType };
|
|
18474
|
+
if (safeUrl.startsWith("/assets/")) headers["Cache-Control"] = "public, max-age=31536000, immutable";
|
|
18475
|
+
res.writeHead(200, headers);
|
|
18476
|
+
res.end(data);
|
|
18477
|
+
} catch {
|
|
18478
|
+
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
18479
|
+
res.end("Not found");
|
|
18480
|
+
}
|
|
18481
|
+
}
|
|
18482
|
+
/**
|
|
18459
18483
|
* Watchdog shared by both web entry points. Detects "nobody is using the UI"
|
|
18460
18484
|
* as: zero WebSocket connections AND no HTTP request for `idleMs`, with an
|
|
18461
18485
|
* in-flight agent turn (`busy()`) deferring the exit so background work is
|
|
@@ -19007,84 +19031,7 @@ async function runWebServer(opts) {
|
|
|
19007
19031
|
if (await handleSessionControlRoutes(req, res, url, method, manager)) return;
|
|
19008
19032
|
if (await handleResourceRoutes(req, res, url, method, manager)) return;
|
|
19009
19033
|
if (await handleGlobalRoutes(req, res, url, method, manager)) return;
|
|
19010
|
-
|
|
19011
|
-
if (snapshotMatch && method === "GET") {
|
|
19012
|
-
const sessionId = decodeURIComponent(snapshotMatch[1]);
|
|
19013
|
-
const ws = manager.get(sessionId);
|
|
19014
|
-
if (!ws) {
|
|
19015
|
-
res.writeHead(404, { "Content-Type": "application/json" });
|
|
19016
|
-
res.end(JSON.stringify({
|
|
19017
|
-
code: 404,
|
|
19018
|
-
message: "Session not found"
|
|
19019
|
-
}));
|
|
19020
|
-
return;
|
|
19021
|
-
}
|
|
19022
|
-
try {
|
|
19023
|
-
await ws.ready;
|
|
19024
|
-
const query = new URLSearchParams(url.split("?")[1] ?? "");
|
|
19025
|
-
const tail = Number(query.get("tail") ?? "");
|
|
19026
|
-
sendJson(res, 200, Number.isFinite(tail) && tail > 0 ? ws.getSnapshot({ tail }) : ws.getSnapshot());
|
|
19027
|
-
} catch (error) {
|
|
19028
|
-
sendHttpError(res, error);
|
|
19029
|
-
}
|
|
19030
|
-
return;
|
|
19031
|
-
}
|
|
19032
|
-
const olderMatch = /^\/api\/v1\/sessions\/([^/?]+)\/messages(\?|$)/.exec(url);
|
|
19033
|
-
if (olderMatch && method === "GET") {
|
|
19034
|
-
const sessionId = decodeURIComponent(olderMatch[1]);
|
|
19035
|
-
const ws = manager.get(sessionId);
|
|
19036
|
-
if (!ws) {
|
|
19037
|
-
res.writeHead(404, { "Content-Type": "application/json" });
|
|
19038
|
-
res.end(JSON.stringify({
|
|
19039
|
-
code: 404,
|
|
19040
|
-
message: "Session not found"
|
|
19041
|
-
}));
|
|
19042
|
-
return;
|
|
19043
|
-
}
|
|
19044
|
-
try {
|
|
19045
|
-
await ws.ready;
|
|
19046
|
-
const query = new URLSearchParams(url.split("?")[1] ?? "");
|
|
19047
|
-
const seq = Number(query.get("seq") ?? "0");
|
|
19048
|
-
const tool = query.get("tool") ?? "";
|
|
19049
|
-
if (Number.isFinite(seq) && seq > 0 && tool) {
|
|
19050
|
-
sendJson(res, 200, { output: ws.getThinkingEntry(seq, tool) });
|
|
19051
|
-
return;
|
|
19052
|
-
}
|
|
19053
|
-
const before = Number(query.get("before") ?? "0");
|
|
19054
|
-
const tail = Number(query.get("tail") ?? "50");
|
|
19055
|
-
sendJson(res, 200, Number.isFinite(before) && before > 0 ? ws.getMessagesOlder(before, Number.isFinite(tail) && tail > 0 ? tail : 50) : {
|
|
19056
|
-
messages: [],
|
|
19057
|
-
hasMore: false
|
|
19058
|
-
});
|
|
19059
|
-
} catch (error) {
|
|
19060
|
-
sendHttpError(res, error);
|
|
19061
|
-
}
|
|
19062
|
-
return;
|
|
19063
|
-
}
|
|
19064
|
-
if (url === `${API_PREFIX}/git/status` && method === "GET") {
|
|
19065
|
-
const gs = await getGitStatus(workDir);
|
|
19066
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
19067
|
-
res.end(JSON.stringify(gs));
|
|
19068
|
-
return;
|
|
19069
|
-
}
|
|
19070
|
-
if (url.startsWith(`${API_PREFIX}/git/diff?`) && method === "GET") {
|
|
19071
|
-
const relPath = new URLSearchParams(url.split("?")[1] ?? "").get("path") ?? "";
|
|
19072
|
-
try {
|
|
19073
|
-
const result = await getGitFileDiff(workDir, relPath);
|
|
19074
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
19075
|
-
res.end(JSON.stringify({
|
|
19076
|
-
path: relPath,
|
|
19077
|
-
patch: result?.patch ?? ""
|
|
19078
|
-
}));
|
|
19079
|
-
} catch (error) {
|
|
19080
|
-
sendHttpError(res, error);
|
|
19081
|
-
}
|
|
19082
|
-
return;
|
|
19083
|
-
}
|
|
19084
|
-
function makeFileGate() {
|
|
19085
|
-
return new FileGate(() => manager.list().map((s) => s.workDir));
|
|
19086
|
-
}
|
|
19087
|
-
if (await handleFilesRoutes(req, res, url, method, API_PREFIX, makeFileGate())) return;
|
|
19034
|
+
if (await handleSessionDataRoutes(req, res, url, method, (sessionId) => manager.get(sessionId), workDir, new FileGate(() => manager.list().map((s) => s.workDir)))) return;
|
|
19088
19035
|
if (url === `${API_PREFIX}/like` && method === "GET") {
|
|
19089
19036
|
try {
|
|
19090
19037
|
sendJson(res, 200, await loadLikePreferences());
|
|
@@ -19292,33 +19239,7 @@ async function runWebServer(opts) {
|
|
|
19292
19239
|
}
|
|
19293
19240
|
return;
|
|
19294
19241
|
}
|
|
19295
|
-
|
|
19296
|
-
try {
|
|
19297
|
-
const html = await readFile(join(publicDir, "index.html"), "utf-8");
|
|
19298
|
-
res.writeHead(200, {
|
|
19299
|
-
"Content-Type": "text/html; charset=utf-8",
|
|
19300
|
-
"Cache-Control": "no-store"
|
|
19301
|
-
});
|
|
19302
|
-
res.end(html);
|
|
19303
|
-
} catch {
|
|
19304
|
-
res.writeHead(500, { "Content-Type": "text/plain" });
|
|
19305
|
-
res.end("Failed to load web UI. Did you run pnpm web:build?");
|
|
19306
|
-
}
|
|
19307
|
-
return;
|
|
19308
|
-
}
|
|
19309
|
-
const safeUrl = url.replaceAll(/\?.*$/g, "").replaceAll(/\.{2,}/g, "");
|
|
19310
|
-
try {
|
|
19311
|
-
const filePath = join(publicDir, safeUrl);
|
|
19312
|
-
const contentType = contentTypes[filePath.split(".").pop() ?? ""] ?? "application/octet-stream";
|
|
19313
|
-
const data = await readFile(filePath);
|
|
19314
|
-
const headers = { "Content-Type": contentType };
|
|
19315
|
-
if (safeUrl.startsWith("/assets/")) headers["Cache-Control"] = "public, max-age=31536000, immutable";
|
|
19316
|
-
res.writeHead(200, headers);
|
|
19317
|
-
res.end(data);
|
|
19318
|
-
} catch {
|
|
19319
|
-
res.writeHead(404, { "Content-Type": "text/plain" });
|
|
19320
|
-
res.end("Not found");
|
|
19321
|
-
}
|
|
19242
|
+
await handleStaticRoutes(res, url, publicDir);
|
|
19322
19243
|
});
|
|
19323
19244
|
const wss = new WebSocketServer({ server: httpServer });
|
|
19324
19245
|
wss.on("error", () => {});
|
|
@@ -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 {
|
|
6
|
+
import { nn as handleConnectCommand } from "./dispatch-La1sAZPF.mjs";
|
|
7
7
|
export { handleConnectCommand };
|