scream-code 0.18.8 → 0.18.9
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-Db7f8Kja.mjs → app-D3QT1bx1.mjs} +258 -23
- package/dist/{dispatch-BPfUTccZ.mjs → dispatch-BcRHd4ya.mjs} +105 -42
- package/dist/{dispatch-zsFzFFoY.mjs → dispatch-JYsyD0aN.mjs} +1 -1
- package/dist/main.mjs +1 -1
- package/dist/{markit-CVQeFGFG.mjs → markit-CV3BXOV_.mjs} +20 -13
- package/dist/{src-DA34cXSv.mjs → src-B1S88rK6.mjs} +1 -1
- package/dist/{src-ClB_Hzp9.mjs → src-DIVvoAYO.mjs} +242 -27
- package/dist/{text-input-dialog-CFRUSCi6.mjs → text-input-dialog-CgAOMXv1.mjs} +1 -1
- package/dist/{text-input-dialog-DHDsHCqR.mjs → text-input-dialog-CqagQQtW.mjs} +38 -10
- package/package.json +1 -1
|
@@ -4,9 +4,9 @@ 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 { A as sharedMemoStore } from "./src-
|
|
8
|
-
import { $ as clearGoalState, $n as
|
|
9
|
-
import { i as t, n as getLocale, r as setLocale } from "./text-input-dialog-
|
|
7
|
+
import { A as sharedMemoStore } from "./src-DIVvoAYO.mjs";
|
|
8
|
+
import { $ as clearGoalState, $n as DEFAULT_CATALOG_URL, $t as isStreaming, A as renderDiffLines, An as sortSlashCommands, At as createMarkdownTheme, B as SkillActivationComponent, Bn as TuiConfigParseError, Bt as DISABLE_TERMINAL_THEME_REPORTING, C as appendJsonlLine, Cn as TIP_ROTATION_INTERVAL_MS, Ct as refreshProviderBalance, Dn as getNoActiveSessionMessage, E as getDaemonInstructions, En as getLlmNotSetMessage, F as ThinkingComponent, Fn as getKnowledgeStore, Ft as contrastTextHex, G as getSharedSpeedTracker, Gn as getDataDir, Gt as OSC11_RESPONSE_PREFIX, H as ActivityGroupComponent, Hn as loadTuiConfig, Ht as ENABLE_TERMINAL_THEME_REPORTING, I as NoticeMessageComponent, In as hasEmbeddingModelCache, It as getColorPalette, J as WelcomeComponent, Jn as detectInstallSource, Jt as TERMINAL_FOCUS_IN, K as BackgroundAgentStatusComponent, Kn as getInputHistoryFile, Kt as OSC11_RESPONSE_PREFIX_NO_ESC, L as StatusMessageComponent, Ln as startManualEmbeddingDownload, Lt as detectTerminalTheme, M as highlightLines, Mn as setExperimentalFlags, Mt as isTurnElapsedEnabled, N as langFromPath, Nn as embeddingProgressLabel, Nt as toggleEmptySessionHint, O as UserMessageComponent, On as buildSkillSlashCommands, Ot as resolveThemeSync, P as CachedContainer, Pn as embeddingFailureDetail, Pt as createThemeStyles, Q as CompactionComponent, Qn as PRODUCT_NAME, Qt as isBusy, R as replaceTabs, Rn as PIXEL_PULSE_FRAMES, Rt as parseOsc11BackgroundTheme, S as readUpdateCache, Sn as SESSION_TIPS, Tn as getCtrlDHint, Tt as clearInfoPanelState, U as charsForTokenBudget, Un as saveTuiConfig, Ut as OSC11_QUERY, V as AssistantMessageComponent, Vn as TuiLikePreferencesSchema, Vt as ENABLE_TERMINAL_FOCUS_REPORTING, W as estimateTokens, Wn as detectShellEnvironment, Wt as OSC11_RESPONSE, X as getBreathingFrame, Xn as CLI_UI_MODE, Xt as TERMINAL_THEME_DARK, Y as BREATHE_CYCLE_MS, Yn as CLI_COMMAND_NAME, Yt as TERMINAL_FOCUS_OUT, Z as resetBreathingClock, Zn as CLI_USER_AGENT_PRODUCT, Zt as TERMINAL_THEME_LIGHT, _n as stringValue, _r as ErrorCodes, a as buildRoleAdditionalText, ar as appendSessionIndexEntry, b as selectUpdateTarget, bn as EXIT_CONFIRM_WINDOW_MS, cn as printableChar, ct as changeThinkingLevel, d as hasDispose, dn as appendStreamingArgsPreview, dr as resolveScreamHome, en as FooterComponent, er as fetchCatalog, et as refineGoal, f as isExpandable, fn as argsRecord, fr as flushDiagnosticLogs, gn as serializeToolResultOutput, gr as isOrphanedToolCallError, gt as handlePlanCommand, h as formatMemoryMemoForInjection, hn as parseStreamingArgs, hr as isScreamError, i as openUrl, ir as normalizeWorkDir, j as renderDiffLinesClustered, jn as isExperimentalFlagEnabled, jt as isEmptySessionHintDismissed, k as ToolCallComponent, kn as BUILTIN_SLASH_COMMANDS, kt as createEditorTheme, ln as STATUS_BULLET, lr as isRealUserPrompt, lt as getModelCycleLevel, m as MoonLoader, mn as isTodoItemShape, mr as resolveGlobalLogPath, mt as handleFusionPlanCommand, n as clearEvalPanelState, nn as lerpHex, nr as ScreamHarness, o as writeTextClipboard, or as readSessionIndex, ot as isInternalMessage, p as isPlanExpandable, pn as formatErrorMessage, pr as log, q as AgentGroupComponent, qn as getLogDir, qt as QUERY_TERMINAL_THEME, rn as SubagentSlots, rr as encodeWorkDirKey, s as syncDiagramCapabilityPrompt, sr as removeSessionIndexEntry, st as toTerminalHyperlink, t as dispatchInput, tn as lerpGradient, tr as saveCatalogCache, u as disposeChildren, un as appendSessionHeaderHint, ur as parseRlmMaxDepthArg, vn as truncateErrorMessage, vr as SCREAM_ERROR_INFO, w as readJsonlFile, wn as getCtrlCHint, wt as supportsBalance, x as refreshUpdateCache, xn as MAIN_AGENT_ID, z as sanitizeShellOutput, zn as PULSE_WAVE_FRAMES, zt as DISABLE_TERMINAL_FOCUS_REPORTING } from "./dispatch-BcRHd4ya.mjs";
|
|
9
|
+
import { i as t, n as getLocale, r as setLocale } from "./text-input-dialog-CqagQQtW.mjs";
|
|
10
10
|
import { createRequire } from "node:module";
|
|
11
11
|
import { randomBytes, randomUUID, scryptSync, timingSafeEqual } from "node:crypto";
|
|
12
12
|
import { access, appendFile, chmod, mkdir, mkdtemp, readFile, readdir, realpath, rename, rm, stat, unlink, writeFile } from "node:fs/promises";
|
|
@@ -33,7 +33,7 @@ function optionalBuildString(value) {
|
|
|
33
33
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
34
34
|
}
|
|
35
35
|
const SCREAM_BUILD_INFO = {
|
|
36
|
-
version: optionalBuildString("0.18.
|
|
36
|
+
version: optionalBuildString("0.18.9"),
|
|
37
37
|
channel: optionalBuildString(""),
|
|
38
38
|
commit: optionalBuildString(""),
|
|
39
39
|
buildTarget: optionalBuildString("darwin-arm64")
|
|
@@ -2997,6 +2997,19 @@ const INITIAL_LIVE_PANE = {
|
|
|
2997
2997
|
function sliceLeading(text, max = 48) {
|
|
2998
2998
|
return text.length > max ? `${text.slice(0, max)}…` : text;
|
|
2999
2999
|
}
|
|
3000
|
+
/**
|
|
3001
|
+
* Inbound events that prove the stream is still delivering. `TUIState.lastActivityAt`
|
|
3002
|
+
* is stamped from this set so the status-bar wave can colour a stream that went
|
|
3003
|
+
* silent mid-reasoning — before the 60s transport-level stall timeout fires.
|
|
3004
|
+
*/
|
|
3005
|
+
const ACTIVITY_EVENT_TYPES = new Set([
|
|
3006
|
+
"assistant.delta",
|
|
3007
|
+
"thinking.delta",
|
|
3008
|
+
"tool.call.started",
|
|
3009
|
+
"tool.call.delta",
|
|
3010
|
+
"tool.progress",
|
|
3011
|
+
"tool.result"
|
|
3012
|
+
]);
|
|
3000
3013
|
function addTokenUsage(a, b) {
|
|
3001
3014
|
return {
|
|
3002
3015
|
inputOther: a.inputOther + b.inputOther,
|
|
@@ -3186,6 +3199,7 @@ var SessionEventHandler = class {
|
|
|
3186
3199
|
if (hidden.length > 0) host.showStatus(formatMcpStartupStatusSummary(hidden, visible.length), host.state.theme.colors.textMuted);
|
|
3187
3200
|
}
|
|
3188
3201
|
handleEvent(event, sendQueued) {
|
|
3202
|
+
if (ACTIVITY_EVENT_TYPES.has(event.type)) this.host.state.lastActivityAt = Date.now();
|
|
3189
3203
|
if (this.routeSubagentEvent(event)) return;
|
|
3190
3204
|
if ("turnId" in event && event.turnId !== void 0) this.host.streamingUI.setTurnId(String(event.turnId));
|
|
3191
3205
|
switch (event.type) {
|
|
@@ -4057,7 +4071,10 @@ var SessionEventHandler = class {
|
|
|
4057
4071
|
if (next !== void 0) setTimeout(() => {
|
|
4058
4072
|
sendQueued(next);
|
|
4059
4073
|
}, 0);
|
|
4060
|
-
} else this.host.setAppState({
|
|
4074
|
+
} else this.host.setAppState({
|
|
4075
|
+
isCompacting: false,
|
|
4076
|
+
streamingStartTime: Date.now()
|
|
4077
|
+
});
|
|
4061
4078
|
}
|
|
4062
4079
|
handleSubagentSpawned(event) {
|
|
4063
4080
|
this.subagentSlots.onSpawned(event.subagentId, event.subagentName, event.description);
|
|
@@ -8899,6 +8916,49 @@ function installTerminalThemeTracking(state, onTheme) {
|
|
|
8899
8916
|
};
|
|
8900
8917
|
}
|
|
8901
8918
|
//#endregion
|
|
8919
|
+
//#region src/tui/utils/wave-color.ts
|
|
8920
|
+
/**
|
|
8921
|
+
* Silence ramp for the status-bar pulse wave.
|
|
8922
|
+
*
|
|
8923
|
+
* The wave reports one thing: how long the agent has been working without
|
|
8924
|
+
* receiving anything. That covers a request awaiting its first token, a
|
|
8925
|
+
* reasoning or text stream that stopped delivering, and a tool that has been
|
|
8926
|
+
* running without progress. Any inbound event resets the clock, so the wave
|
|
8927
|
+
* returns to the brand colour the moment work resumes.
|
|
8928
|
+
*
|
|
8929
|
+
* Timeline (elapsed since the last inbound event, or since the request was
|
|
8930
|
+
* sent while no token has arrived yet):
|
|
8931
|
+
* 0 – 10s brand green, nothing to report
|
|
8932
|
+
* 10 – 15s green → amber
|
|
8933
|
+
* 15 – 25s amber → red (15s is pure amber, 25s pure red)
|
|
8934
|
+
* ≥ 25s red
|
|
8935
|
+
*
|
|
8936
|
+
* Red is an early warning, not an error: retries are driven by real transport
|
|
8937
|
+
* failures (the stall timeout, disconnects, rate limits), never by this colour.
|
|
8938
|
+
*
|
|
8939
|
+
* Colours come from the active palette (primary / warning / error), so light
|
|
8940
|
+
* and dark themes each ramp between their own contrast-checked values and a
|
|
8941
|
+
* theme switch takes effect on the next frame.
|
|
8942
|
+
*/
|
|
8943
|
+
/** Green is held this long before the ramp starts. */
|
|
8944
|
+
const WAVE_GREEN_HOLD_MS = 1e4;
|
|
8945
|
+
/** Pure amber is reached here. */
|
|
8946
|
+
const WAVE_AMBER_AT_MS = 15e3;
|
|
8947
|
+
/** Pure red is reached here. */
|
|
8948
|
+
const WAVE_RED_AT_MS = 25e3;
|
|
8949
|
+
/**
|
|
8950
|
+
* Colour for a request that has been waiting `elapsedMs`.
|
|
8951
|
+
*
|
|
8952
|
+
* Non-finite or negative input falls back to green: a broken clock must never
|
|
8953
|
+
* make the indicator claim a stall.
|
|
8954
|
+
*/
|
|
8955
|
+
function resolveWaveColor(elapsedMs, stops) {
|
|
8956
|
+
if (!Number.isFinite(elapsedMs) || elapsedMs < 1e4) return stops.green;
|
|
8957
|
+
if (elapsedMs < 15e3) return lerpHex(stops.green, stops.amber, (elapsedMs - WAVE_GREEN_HOLD_MS) / (WAVE_AMBER_AT_MS - WAVE_GREEN_HOLD_MS));
|
|
8958
|
+
if (elapsedMs < 25e3) return lerpHex(stops.amber, stops.red, (elapsedMs - WAVE_AMBER_AT_MS) / (WAVE_RED_AT_MS - WAVE_AMBER_AT_MS));
|
|
8959
|
+
return stops.red;
|
|
8960
|
+
}
|
|
8961
|
+
//#endregion
|
|
8902
8962
|
//#region src/tui/components/chrome/pulse-wave-loader.ts
|
|
8903
8963
|
/** Leading/trailing glyph: U+2588 (Block Elements — guaranteed single-column
|
|
8904
8964
|
* width). The remaining stage cells render muted middle dots (U+00B7). */
|
|
@@ -8925,7 +8985,9 @@ var PulseWaveLoader = class extends Text {
|
|
|
8925
8985
|
currentFrame = 0;
|
|
8926
8986
|
intervalId = null;
|
|
8927
8987
|
ui;
|
|
8928
|
-
|
|
8988
|
+
/** Resolved on every frame so a theme switch lands immediately and the
|
|
8989
|
+
* first-token ramp can advance without rebuilding the status bar. */
|
|
8990
|
+
resolveColor;
|
|
8929
8991
|
/** Wall-clock time of the last frame advance, for drift-free scheduling. */
|
|
8930
8992
|
lastTickAt = 0;
|
|
8931
8993
|
/** Raw frame text without Text's full-width render padding, exposed so
|
|
@@ -8936,10 +8998,10 @@ var PulseWaveLoader = class extends Text {
|
|
|
8936
8998
|
getFrameText() {
|
|
8937
8999
|
return this.frameText;
|
|
8938
9000
|
}
|
|
8939
|
-
constructor(ui,
|
|
9001
|
+
constructor(ui, resolveColor) {
|
|
8940
9002
|
super("", 1, 0);
|
|
8941
9003
|
this.ui = ui;
|
|
8942
|
-
this.
|
|
9004
|
+
this.resolveColor = resolveColor;
|
|
8943
9005
|
this.start();
|
|
8944
9006
|
}
|
|
8945
9007
|
start() {
|
|
@@ -8953,6 +9015,12 @@ var PulseWaveLoader = class extends Text {
|
|
|
8953
9015
|
this.intervalId = null;
|
|
8954
9016
|
}
|
|
8955
9017
|
}
|
|
9018
|
+
/** Re-resolve the colour and repaint now. The cached frame text still carries
|
|
9019
|
+
* the previous colour, and the next scheduled tick can be up to 80ms away —
|
|
9020
|
+
* a palette swapped in place should land on the frame that follows it. */
|
|
9021
|
+
repaint() {
|
|
9022
|
+
this.updateDisplay();
|
|
9023
|
+
}
|
|
8956
9024
|
dispose() {
|
|
8957
9025
|
this.stop();
|
|
8958
9026
|
}
|
|
@@ -8981,21 +9049,18 @@ var PulseWaveLoader = class extends Text {
|
|
|
8981
9049
|
}, delayMs);
|
|
8982
9050
|
this.intervalId = timer;
|
|
8983
9051
|
}
|
|
8984
|
-
setColorHex(colorHex) {
|
|
8985
|
-
this.colorHex = colorHex;
|
|
8986
|
-
this.updateDisplay();
|
|
8987
|
-
}
|
|
8988
9052
|
updateDisplay() {
|
|
8989
9053
|
const step = PULSE_WAVE_FRAMES[this.currentFrame] ?? PULSE_WAVE_FRAMES[0];
|
|
8990
|
-
const
|
|
9054
|
+
const color = this.resolveColor();
|
|
9055
|
+
const cells = Array.from({ length: 8 }, (_, idx) => this.renderCell(idx, step.active, step.forward, color));
|
|
8991
9056
|
this.frameText = cells.join("");
|
|
8992
9057
|
this.setText(this.frameText);
|
|
8993
9058
|
this.ui.requestRender();
|
|
8994
9059
|
}
|
|
8995
|
-
renderCell(index, active, forward) {
|
|
9060
|
+
renderCell(index, active, forward, color) {
|
|
8996
9061
|
const distance = forward ? active - index : index - active;
|
|
8997
|
-
if (distance === 0) return chalk.hex(
|
|
8998
|
-
if (distance === 1) return chalk.hex(
|
|
9062
|
+
if (distance === 0) return chalk.hex(color)(LEADING_BOX);
|
|
9063
|
+
if (distance === 1) return chalk.hex(color).dim(LEADING_BOX);
|
|
8999
9064
|
return chalk.dim("·");
|
|
9000
9065
|
}
|
|
9001
9066
|
};
|
|
@@ -9397,6 +9462,7 @@ var LifecycleController = class LifecycleController {
|
|
|
9397
9462
|
state.theme.resolvedTheme = nextTheme.resolvedTheme;
|
|
9398
9463
|
state.theme.styles = nextTheme.styles;
|
|
9399
9464
|
state.theme.markdownTheme = nextTheme.markdownTheme;
|
|
9465
|
+
this.statusBarLoader?.repaint();
|
|
9400
9466
|
this.host.setAppState({ theme });
|
|
9401
9467
|
this.host.updateEditorBorderHighlight();
|
|
9402
9468
|
for (const child of state.transcriptContainer.children) child.invalidate?.();
|
|
@@ -9451,7 +9517,7 @@ var LifecycleController = class LifecycleController {
|
|
|
9451
9517
|
case "tool":
|
|
9452
9518
|
case "thinking":
|
|
9453
9519
|
{
|
|
9454
|
-
const loader = new PulseWaveLoader(state.ui,
|
|
9520
|
+
const loader = new PulseWaveLoader(state.ui, () => this.currentWaveColor());
|
|
9455
9521
|
this.statusBarLoader = loader;
|
|
9456
9522
|
state.statusBarContainer.addChild(new StatusBarPaneComponent({
|
|
9457
9523
|
mode,
|
|
@@ -9544,6 +9610,32 @@ var LifecycleController = class LifecycleController {
|
|
|
9544
9610
|
this.host.state.terminal.setProgress(active);
|
|
9545
9611
|
this.host.state.terminalState.progressActive = active;
|
|
9546
9612
|
}
|
|
9613
|
+
/**
|
|
9614
|
+
* Colour for the status-bar pulse wave.
|
|
9615
|
+
*
|
|
9616
|
+
* Measures silence in whatever the agent is doing: a request awaiting its
|
|
9617
|
+
* first token, a reasoning/text stream that stopped delivering, or a tool
|
|
9618
|
+
* that has been running without emitting progress. Red is an early warning
|
|
9619
|
+
* only — it never triggers a retry, because retries are driven by real
|
|
9620
|
+
* transport errors (the 60s stall timeout, disconnects, rate limits).
|
|
9621
|
+
*
|
|
9622
|
+
* Resolved per frame, so the ramp advances and a live theme switch applies
|
|
9623
|
+
* without rebuilding the status bar.
|
|
9624
|
+
*/
|
|
9625
|
+
currentWaveColor() {
|
|
9626
|
+
const { appState, theme, lastActivityAt } = this.host.state;
|
|
9627
|
+
const colors = theme.colors;
|
|
9628
|
+
const { streamingPhase, streamingStartTime, reconnectAttempt } = appState;
|
|
9629
|
+
if (streamingPhase === "idle") return colors.primary;
|
|
9630
|
+
const anchor = Math.max(lastActivityAt, streamingStartTime);
|
|
9631
|
+
if (anchor === 0) return colors.primary;
|
|
9632
|
+
const elapsed = Date.now() - anchor;
|
|
9633
|
+
return resolveWaveColor(reconnectAttempt > 0 ? Math.max(elapsed, WAVE_AMBER_AT_MS) : elapsed, {
|
|
9634
|
+
green: colors.primary,
|
|
9635
|
+
amber: colors.warning,
|
|
9636
|
+
red: colors.error
|
|
9637
|
+
});
|
|
9638
|
+
}
|
|
9547
9639
|
stopActivitySpinner() {
|
|
9548
9640
|
if (this.host.state.activitySpinner !== null) {
|
|
9549
9641
|
this.host.state.activitySpinner.instance.stop();
|
|
@@ -11669,6 +11761,7 @@ function createTUIState(options) {
|
|
|
11669
11761
|
activeDialog: null,
|
|
11670
11762
|
tasksBrowser: void 0,
|
|
11671
11763
|
externalEditorRunning: false,
|
|
11764
|
+
lastActivityAt: 0,
|
|
11672
11765
|
queuedMessages: [],
|
|
11673
11766
|
fdPath: detectFdPath(),
|
|
11674
11767
|
gitLsFilesCache: createGitLsFilesCache(initialAppState.workDir),
|
|
@@ -12474,6 +12567,11 @@ var SessionManager$1 = class {
|
|
|
12474
12567
|
resetSessionRuntime() {
|
|
12475
12568
|
this.host.state.queuedMessages = [];
|
|
12476
12569
|
this.host.harness.interactiveAgentId = MAIN_AGENT_ID;
|
|
12570
|
+
this.host.setAppState({
|
|
12571
|
+
streamingPhase: "idle",
|
|
12572
|
+
streamingStartTime: 0
|
|
12573
|
+
});
|
|
12574
|
+
this.host.state.lastActivityAt = 0;
|
|
12477
12575
|
this.host.streamingUI.discardPending();
|
|
12478
12576
|
this.host.streamingUI.resetToolCallState();
|
|
12479
12577
|
this.host.streamingUI.resetToolUi();
|
|
@@ -13160,6 +13258,8 @@ var HelpPanelComponent = class extends Container {
|
|
|
13160
13258
|
* Esc Cancel / back
|
|
13161
13259
|
*/
|
|
13162
13260
|
const ELLIPSIS$1 = "…";
|
|
13261
|
+
/** One-sentence conclusion: generous for a rule, bounded for prompt injection. */
|
|
13262
|
+
const MAX_DISTILLED_CHARS = 200;
|
|
13163
13263
|
function formatRelativeTime$1(ts) {
|
|
13164
13264
|
if (!Number.isFinite(ts) || ts <= 0) return "";
|
|
13165
13265
|
const diffSec = Math.floor(Math.max(0, Date.now() - ts) / 1e3);
|
|
@@ -13170,6 +13270,13 @@ function formatRelativeTime$1(ts) {
|
|
|
13170
13270
|
if (hours < 24) return t("memory.hours_ago", { hours });
|
|
13171
13271
|
return t("memory.days_ago", { days: Math.floor(hours / 24) });
|
|
13172
13272
|
}
|
|
13273
|
+
/** Local calendar date as YYYY-MM-DD; avoids the UTC off-by-one of toISOString. */
|
|
13274
|
+
function formatDate(ts) {
|
|
13275
|
+
const date = new Date(ts);
|
|
13276
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
13277
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
13278
|
+
return `${date.getFullYear()}-${month}-${day}`;
|
|
13279
|
+
}
|
|
13173
13280
|
function singleLine$1(text) {
|
|
13174
13281
|
return text.replaceAll(/\s+/g, " ").trim();
|
|
13175
13282
|
}
|
|
@@ -13227,6 +13334,12 @@ var MemoryPickerComponent = class extends Container {
|
|
|
13227
13334
|
searchQuery = "";
|
|
13228
13335
|
isSearching = false;
|
|
13229
13336
|
searchInput = "";
|
|
13337
|
+
/** Draft text for the in-place edit of the latest distillation. */
|
|
13338
|
+
editBuffer = "";
|
|
13339
|
+
/** Set when the last save failed; keeps the draft on screen for a retry. */
|
|
13340
|
+
editError = false;
|
|
13341
|
+
/** Guards against a second Enter while the update is in flight. */
|
|
13342
|
+
saving = false;
|
|
13230
13343
|
/** Memo ids ticked for batch delete (space toggles, a selects all). */
|
|
13231
13344
|
selectedIds = /* @__PURE__ */ new Set();
|
|
13232
13345
|
memos;
|
|
@@ -13287,6 +13400,29 @@ var MemoryPickerComponent = class extends Container {
|
|
|
13287
13400
|
if (ch.length > 0) this.searchInput += ch;
|
|
13288
13401
|
return;
|
|
13289
13402
|
}
|
|
13403
|
+
if (this.mode === "editDistilled") {
|
|
13404
|
+
if (matchesKey(data, Key.escape)) {
|
|
13405
|
+
this.editBuffer = "";
|
|
13406
|
+
this.mode = "detail";
|
|
13407
|
+
this.ui?.requestRender();
|
|
13408
|
+
return;
|
|
13409
|
+
}
|
|
13410
|
+
if (matchesKey(data, Key.enter)) {
|
|
13411
|
+
if (!this.saving) this.saveDistilled();
|
|
13412
|
+
return;
|
|
13413
|
+
}
|
|
13414
|
+
if (matchesKey(data, Key.backspace) || matchesKey(data, Key.delete)) {
|
|
13415
|
+
this.editBuffer = Array.from(this.editBuffer).slice(0, -1).join("");
|
|
13416
|
+
this.ui?.requestRender();
|
|
13417
|
+
return;
|
|
13418
|
+
}
|
|
13419
|
+
const typed = printableChar(data);
|
|
13420
|
+
if (typed.length > 0) {
|
|
13421
|
+
if (Array.from(this.editBuffer).length < MAX_DISTILLED_CHARS) this.editBuffer += typed;
|
|
13422
|
+
this.ui?.requestRender();
|
|
13423
|
+
}
|
|
13424
|
+
return;
|
|
13425
|
+
}
|
|
13290
13426
|
if (this.mode === "confirmDelete") {
|
|
13291
13427
|
if (matchesKey(data, Key.enter)) {
|
|
13292
13428
|
if (this.selectedIds.size > 0) this.deleteSelectedAndReload();
|
|
@@ -13308,6 +13444,14 @@ var MemoryPickerComponent = class extends Container {
|
|
|
13308
13444
|
this.detailMemo = null;
|
|
13309
13445
|
return;
|
|
13310
13446
|
}
|
|
13447
|
+
const key = printableChar(data);
|
|
13448
|
+
if ((key === "e" || key === "E") && this.detailMemo !== null) {
|
|
13449
|
+
this.editBuffer = this.detailMemo.distilled ?? "";
|
|
13450
|
+
this.editError = false;
|
|
13451
|
+
this.mode = "editDistilled";
|
|
13452
|
+
this.ui?.requestRender();
|
|
13453
|
+
return;
|
|
13454
|
+
}
|
|
13311
13455
|
}
|
|
13312
13456
|
if (matchesKey(data, Key.escape)) {
|
|
13313
13457
|
if (this.searchQuery.length > 0) {
|
|
@@ -13376,6 +13520,52 @@ var MemoryPickerComponent = class extends Container {
|
|
|
13376
13520
|
if (this.detailMemo) this.mode = "detail";
|
|
13377
13521
|
this.ui?.requestRender();
|
|
13378
13522
|
}
|
|
13523
|
+
/**
|
|
13524
|
+
* Persist the edited distillation. A non-empty text becomes a user-authored
|
|
13525
|
+
* rule; clearing it drops back to a plain extracted memo.
|
|
13526
|
+
*/
|
|
13527
|
+
async saveDistilled() {
|
|
13528
|
+
const memo = this.detailMemo;
|
|
13529
|
+
if (memo === null) {
|
|
13530
|
+
this.mode = "list";
|
|
13531
|
+
return;
|
|
13532
|
+
}
|
|
13533
|
+
this.saving = true;
|
|
13534
|
+
const text = this.editBuffer.trim();
|
|
13535
|
+
if (text === (memo.distilled ?? "").trim()) {
|
|
13536
|
+
this.saving = false;
|
|
13537
|
+
this.editBuffer = "";
|
|
13538
|
+
this.mode = "detail";
|
|
13539
|
+
this.ui?.requestRender();
|
|
13540
|
+
return;
|
|
13541
|
+
}
|
|
13542
|
+
try {
|
|
13543
|
+
await this.store.update(memo.id, {
|
|
13544
|
+
distilled: text.length > 0 ? text : void 0,
|
|
13545
|
+
distilledFrom: text.length > 0 ? memo.distilledFrom : void 0,
|
|
13546
|
+
origin: text.length > 0 ? "user" : "session",
|
|
13547
|
+
distilledAt: text.length > 0 ? Date.now() : void 0
|
|
13548
|
+
});
|
|
13549
|
+
} catch {
|
|
13550
|
+
this.editError = true;
|
|
13551
|
+
this.saving = false;
|
|
13552
|
+
this.ui?.requestRender();
|
|
13553
|
+
return;
|
|
13554
|
+
}
|
|
13555
|
+
this.saving = false;
|
|
13556
|
+
this.editError = false;
|
|
13557
|
+
this.editBuffer = "";
|
|
13558
|
+
await this.loadMemos();
|
|
13559
|
+
const index = this.memos.findIndex((item) => item.id === memo.id);
|
|
13560
|
+
if (index < 0) {
|
|
13561
|
+
this.detailMemo = null;
|
|
13562
|
+
this.mode = "list";
|
|
13563
|
+
this.ui?.requestRender();
|
|
13564
|
+
return;
|
|
13565
|
+
}
|
|
13566
|
+
this.selectedIndex = index;
|
|
13567
|
+
await this.showDetail();
|
|
13568
|
+
}
|
|
13379
13569
|
async deleteAndReload(id) {
|
|
13380
13570
|
try {
|
|
13381
13571
|
await this.store.delete(id);
|
|
@@ -13396,8 +13586,7 @@ var MemoryPickerComponent = class extends Container {
|
|
|
13396
13586
|
}
|
|
13397
13587
|
render(width) {
|
|
13398
13588
|
const c = this.colors;
|
|
13399
|
-
const lines = [];
|
|
13400
|
-
lines.push(chalk.hex(c.primary)("─".repeat(width)));
|
|
13589
|
+
const lines = [chalk.hex(c.primary)("─".repeat(width))];
|
|
13401
13590
|
if (this.isSearching) {
|
|
13402
13591
|
const prompt = t("memory.search_label");
|
|
13403
13592
|
const input = this.searchInput.length > 0 ? this.searchInput : "█";
|
|
@@ -13426,15 +13615,18 @@ var MemoryPickerComponent = class extends Container {
|
|
|
13426
13615
|
return lines;
|
|
13427
13616
|
}
|
|
13428
13617
|
if (this.mode === "detail" && this.detailMemo) return this.renderDetail(lines, width, c);
|
|
13618
|
+
if (this.mode === "editDistilled" && this.detailMemo) return this.renderEditDistilled(lines, width, c);
|
|
13429
13619
|
if (this.mode === "confirmDelete") {
|
|
13430
13620
|
if (this.selectedIds.size > 0) {
|
|
13431
13621
|
lines.push(truncateToWidth(chalk.hex(c.warning).bold(t("memory.batch_delete_confirm", { count: String(this.selectedIds.size) })), width, ELLIPSIS$1));
|
|
13432
13622
|
lines.push(chalk.hex(c.warning)(t("memory.batch_delete_hint")));
|
|
13623
|
+
if (this.memos.some((memo) => this.selectedIds.has(memo.id) && memo.origin !== void 0 && memo.origin !== "session")) lines.push(chalk.hex(c.warning)(truncateToWidth(` ${t("memory.delete_rule_warning")}`, width, ELLIPSIS$1)));
|
|
13433
13624
|
} else {
|
|
13434
13625
|
const memo = this.memos[this.selectedIndex];
|
|
13435
13626
|
if (memo) {
|
|
13436
13627
|
lines.push(truncateToWidth(chalk.hex(c.warning).bold(` ${t("memory.deleting")}${memo.userNeed}`), width, ELLIPSIS$1));
|
|
13437
13628
|
lines.push(chalk.hex(c.warning)(t("memory.delete_confirm_hint")));
|
|
13629
|
+
if (memo.origin !== void 0 && memo.origin !== "session") lines.push(chalk.hex(c.warning)(truncateToWidth(` ${t("memory.delete_rule_warning")}`, width, ELLIPSIS$1)));
|
|
13438
13630
|
}
|
|
13439
13631
|
}
|
|
13440
13632
|
lines.push(chalk.hex(c.primary)("─".repeat(width)));
|
|
@@ -13468,7 +13660,10 @@ var MemoryPickerComponent = class extends Container {
|
|
|
13468
13660
|
const indentWidth = visibleWidth(indent);
|
|
13469
13661
|
const titleColor = isSelected ? c.primary : c.text;
|
|
13470
13662
|
const titleStyle = isSelected ? chalk.hex(titleColor).bold : chalk.hex(titleColor);
|
|
13471
|
-
const
|
|
13663
|
+
const sources = memo.distilledFrom ?? [];
|
|
13664
|
+
const isRule = memo.origin !== void 0 && memo.origin !== "session";
|
|
13665
|
+
const trailingParts = [formatRelativeTime$1(isRule ? memo.distilledAt ?? memo.recordedAt : memo.recordedAt), isRule ? memo.origin === "user" ? t("memory.origin_user") : t("memory.origin_dream") : sourceLabel(memo.extractionSource)].filter((p) => p.length > 0);
|
|
13666
|
+
if (isRule && sources.length > 0) trailingParts.push(t("memory.source_count", { count: String(sources.length) }));
|
|
13472
13667
|
const trailingText = trailingParts.length > 0 ? " " + trailingParts.join(" ") : "";
|
|
13473
13668
|
const trailingWidth = visibleWidth(trailingText);
|
|
13474
13669
|
const headerPrefixWidth = visibleWidth(pointer) + 1 + visibleWidth(check) + 1;
|
|
@@ -13494,17 +13689,22 @@ var MemoryPickerComponent = class extends Container {
|
|
|
13494
13689
|
const approachPreview = t("memory.plan_label") + singleLine$1(memo.approach);
|
|
13495
13690
|
card.push(indent + chalk.hex(c.textDim)(truncateToWidth(approachPreview, Math.max(8, width - indentWidth), ELLIPSIS$1)));
|
|
13496
13691
|
}
|
|
13692
|
+
if (memo.distilled !== void 0 && memo.distilled.length > 0) {
|
|
13693
|
+
const distilledPreview = t("memory.distilled_label") + singleLine$1(memo.distilled);
|
|
13694
|
+
card.push(indent + chalk.hex(c.success ?? c.primary)(truncateToWidth(distilledPreview, Math.max(8, width - indentWidth), ELLIPSIS$1)));
|
|
13695
|
+
}
|
|
13497
13696
|
return card;
|
|
13498
13697
|
}
|
|
13499
13698
|
renderDetail(lines, width, c) {
|
|
13500
13699
|
const memo = this.detailMemo;
|
|
13501
|
-
const time =
|
|
13700
|
+
const time = formatDate(memo.recordedAt);
|
|
13502
13701
|
const sessionLabel = memo.sourceSessionTitle && memo.sourceSessionTitle.length > 0 ? `${memo.sourceSessionTitle} (${memo.sourceSessionId.slice(0, 12)})` : memo.sourceSessionId.slice(0, 12);
|
|
13503
13702
|
const indent = " ";
|
|
13504
13703
|
const contentWidth = Math.max(8, width - visibleWidth(indent));
|
|
13505
13704
|
lines.push(truncateToWidth(chalk.hex(c.primary).bold(`${indent}${t("memory.requirement_label")}${memo.userNeed}`), width, ELLIPSIS$1));
|
|
13506
13705
|
lines.push("");
|
|
13507
|
-
|
|
13706
|
+
const sourceName = memo.origin !== void 0 && memo.origin !== "session" ? memo.origin === "user" ? t("memory.origin_user") : t("memory.origin_dream") : sourceLabel(memo.extractionSource);
|
|
13707
|
+
lines.push(chalk.hex(c.textMuted)(truncateToWidth(`${indent}${t("memory.result_label")}${memo.outcome} ${t("memory.source_label")}${sourceName} ${time}`, width, ELLIPSIS$1)));
|
|
13508
13708
|
lines.push(chalk.hex(c.textMuted)(truncateToWidth(`${indent}${t("memory.session_label")}${sessionLabel}`, width, ELLIPSIS$1)));
|
|
13509
13709
|
const project = formatProject(memo);
|
|
13510
13710
|
const tags = formatTags(memo);
|
|
@@ -13539,6 +13739,27 @@ var MemoryPickerComponent = class extends Container {
|
|
|
13539
13739
|
}
|
|
13540
13740
|
lines.push("");
|
|
13541
13741
|
}
|
|
13742
|
+
if (memo.distilled !== void 0 && memo.distilled.length > 0) {
|
|
13743
|
+
const label = t("memory.distilled_label");
|
|
13744
|
+
const wrapped = wrapText(memo.distilled, contentWidth - visibleWidth(label));
|
|
13745
|
+
for (let i = 0; i < wrapped.length; i++) {
|
|
13746
|
+
const prefix = i === 0 ? `${indent}${label}` : indent + " ".repeat(visibleWidth(label));
|
|
13747
|
+
lines.push(truncateToWidth(chalk.hex(c.success ?? c.primary)(prefix + wrapped[i]), width, ELLIPSIS$1));
|
|
13748
|
+
}
|
|
13749
|
+
lines.push("");
|
|
13750
|
+
}
|
|
13751
|
+
if (memo.origin !== void 0 && memo.origin !== "session") {
|
|
13752
|
+
const distilledAtLabel = memo.distilledAt !== void 0 ? `${t("memory.distilled_at")} ${formatDate(memo.distilledAt)}` : t("memory.distilled_at_unknown");
|
|
13753
|
+
lines.push(chalk.hex(c.textMuted)(truncateToWidth(`${indent}${distilledAtLabel}`, width, ELLIPSIS$1)));
|
|
13754
|
+
const sources = memo.distilledFrom ?? [];
|
|
13755
|
+
lines.push(chalk.hex(c.textMuted)(truncateToWidth(`${indent}${sources.length > 0 ? t("memory.source_count", { count: String(sources.length) }) : t("memory.source_unknown")}`, width, ELLIPSIS$1)));
|
|
13756
|
+
for (const source of sources.slice(0, 5)) {
|
|
13757
|
+
const date = formatDate(source.at);
|
|
13758
|
+
lines.push(chalk.hex(c.textMuted)(truncateToWidth(`${indent}- ${date} · ${singleLine$1(source.title)}`, width, ELLIPSIS$1)));
|
|
13759
|
+
}
|
|
13760
|
+
if (sources.length > 5) lines.push(chalk.hex(c.textDim)(truncateToWidth(`${indent}${t("memory.source_more", { count: String(sources.length - 5) })}`, width, ELLIPSIS$1)));
|
|
13761
|
+
lines.push("");
|
|
13762
|
+
}
|
|
13542
13763
|
if (memo.note !== void 0 && memo.note.length > 0) {
|
|
13543
13764
|
const label = t("memory.note_label");
|
|
13544
13765
|
const wrapped = wrapText(memo.note, contentWidth - visibleWidth(label));
|
|
@@ -13552,6 +13773,20 @@ var MemoryPickerComponent = class extends Container {
|
|
|
13552
13773
|
lines.push(chalk.hex(c.primary)("─".repeat(width)));
|
|
13553
13774
|
return lines;
|
|
13554
13775
|
}
|
|
13776
|
+
renderEditDistilled(lines, width, c) {
|
|
13777
|
+
const memo = this.detailMemo;
|
|
13778
|
+
const indent = " ";
|
|
13779
|
+
lines.push(truncateToWidth(chalk.hex(c.primary).bold(`${indent}${t("memory.requirement_label")}${memo.userNeed}`), width, ELLIPSIS$1));
|
|
13780
|
+
lines.push("");
|
|
13781
|
+
lines.push(chalk.hex(c.textMuted)(truncateToWidth(`${indent}${t("memory.distilled_label")}`, width, ELLIPSIS$1)));
|
|
13782
|
+
const contentWidth = Math.max(8, width - 4);
|
|
13783
|
+
for (const line of wrapText(`${this.editBuffer}█`, contentWidth)) lines.push(chalk.hex(c.success ?? c.primary)(`${indent}${line}`));
|
|
13784
|
+
lines.push("");
|
|
13785
|
+
if (this.editError) lines.push(chalk.hex(c.error)(truncateToWidth(`${indent}${t("memory.edit_save_failed")}`, width, ELLIPSIS$1)));
|
|
13786
|
+
lines.push(chalk.hex(c.textMuted)(truncateToWidth(`${indent}${t("memory.edit_distilled_hint")}`, width, ELLIPSIS$1)));
|
|
13787
|
+
lines.push(chalk.hex(c.primary)("─".repeat(width)));
|
|
13788
|
+
return lines;
|
|
13789
|
+
}
|
|
13555
13790
|
};
|
|
13556
13791
|
//#endregion
|
|
13557
13792
|
//#region src/tui/utils/session-label.ts
|
|
@@ -15321,7 +15556,7 @@ var ScreamTUI = class {
|
|
|
15321
15556
|
const card = new OnboardingCardComponent({
|
|
15322
15557
|
colors: this.state.theme.colors,
|
|
15323
15558
|
onConfigure: () => {
|
|
15324
|
-
import("./dispatch-
|
|
15559
|
+
import("./dispatch-JYsyD0aN.mjs").then(({ handleConnectCommand }) => handleConnectCommand(this, "")).finally(() => {
|
|
15325
15560
|
this.restoreEditor();
|
|
15326
15561
|
onDone?.();
|
|
15327
15562
|
});
|