scream-code 0.14.8 → 0.14.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.
@@ -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 { $t as isTodoItemShape, A as renderDiffLinesClustered, An as CLI_COMMAND_NAME, At as ENABLE_TERMINAL_FOCUS_REPORTING, B as BackgroundAgentStatusComponent, Bn as MemoryMemoStore, Bt as TERMINAL_THEME_LIGHT, Cn as loadTuiConfig, Ct as createThemeStyles, D as toggleEmptySessionHint, Dn as getInputHistoryFile, Dt as parseOsc11BackgroundTheme, E as isTurnElapsedEnabled, En as getDataDir, Et as detectTerminalTheme, F as estimateTokens, Fn as fetchCatalog, Ft as OSC11_RESPONSE_PREFIX_NO_ESC, G as getBreathingFrame, Gn as isOrphanedToolCallError, H as AgentGroupComponent, Hn as log, Ht as isStreaming, I as getSharedSpeedTracker, In as saveCatalogCache, It as QUERY_TERMINAL_THEME, J as refineGoal, Jt as printableChar, K as resetBreathingClock, Kn as ErrorCodes, L as SkillActivationComponent, Ln as ScreamHarness, Lt as TERMINAL_FOCUS_IN, M as langFromPath, Mn as CLI_USER_AGENT_PRODUCT, Mt as OSC11_QUERY, N as CachedContainer, Nn as PRODUCT_NAME, Nt as OSC11_RESPONSE, O as ToolCallComponent, On as getLogDir, Ot as DISABLE_TERMINAL_FOCUS_REPORTING, P as ThinkingComponent, Pn as DEFAULT_CATALOG_URL, Pt as OSC11_RESPONSE_PREFIX, Qt as formatErrorMessage, R as ReadGroupComponent, Rt as TERMINAL_FOCUS_OUT, S as getDaemonInstructions, Sn as TuiLikePreferencesSchema, St as createMarkdownTheme, T as isEmptySessionHintDismissed, Tn as detectShellEnvironment, Tt as getColorPalette, U as WelcomeComponent, Un as resolveGlobalLogPath, Ut as FooterComponent, V as AssistantMessageComponent, Vn as flushDiagnosticLogs, Vt as isBusy, W as BREATHE_CYCLE_MS, Wn as isScreamError, Xt as appendStreamingArgsPreview, Yt as STATUS_BULLET, Zt as argsRecord, _ as refreshUpdateCache, _n as isExperimentalFlagEnabled, _t as clearInfoPanelState, an as EMPTY_SESSION_HINT_URL, b as readJsonlFile, bn as PULSE_WAVE_FRAMES, bt as resolveThemeSync, c as hasDispose, cn as SESSION_TIPS, ct as handlePlanCommand, d as formatMemoryMemoForInjection, dn as getCtrlDHint, en as parseStreamingArgs, et as toTerminalHyperlink, fn as getLlmNotSetMessage, g as selectUpdateTarget, gn as sortSlashCommands, gt as supportsBalance, hn as BUILTIN_SLASH_COMMANDS, ht as refreshProviderBalance, i as buildRoleAdditionalText, in as CHARS_PER_TOKEN, j as highlightLines, jn as CLI_UI_MODE, jt as ENABLE_TERMINAL_THEME_REPORTING, k as renderDiffLines, kn as detectInstallSource, kt as DISABLE_TERMINAL_THEME_REPORTING, l as isPlanExpandable, ln as TIP_ROTATION_INTERVAL_MS, mn as buildSkillSlashCommands, n as clearEvalPanelState, nn as stringValue, nt as getModelCycleLevel, on as EXIT_CONFIRM_WINDOW_MS, ot as handleFusionPlanCommand, pn as getNoActiveSessionMessage, q as clearGoalState, qn as SCREAM_ERROR_INFO, r as openUrl, rn as truncateErrorMessage, s as disposeChildren, sn as MAIN_AGENT_ID, t as dispatchInput, tn as serializeToolResultOutput, tt as changeThinkingLevel, u as MoonLoader, un as getCtrlCHint, v as readUpdateCache, vn as setExperimentalFlags, w as UserMessageComponent, wn as saveTuiConfig, wt as contrastTextHex, xn as TuiConfigParseError, xt as createEditorTheme, y as appendJsonlLine, yn as PIXEL_PULSE_FRAMES, z as parseReadGroupOutput, zn as resolveScreamHome, zt as TERMINAL_THEME_DARK } from "./dispatch-usl5yQnT.mjs";
8
- import { a as setLocale, o as t } from "./text-input-dialog-B0yHChBj.mjs";
7
+ import { $t as isTodoItemShape, A as renderDiffLinesClustered, An as getInputHistoryFile, At as ENABLE_TERMINAL_FOCUS_REPORTING, B as BackgroundAgentStatusComponent, Bn as ScreamHarness, Bt as TERMINAL_THEME_LIGHT, Cn as PULSE_WAVE_FRAMES, Ct as createThemeStyles, D as toggleEmptySessionHint, Dn as saveTuiConfig, Dt as parseOsc11BackgroundTheme, E as isTurnElapsedEnabled, En as loadTuiConfig, Et as detectTerminalTheme, F as estimateTokens, Fn as CLI_USER_AGENT_PRODUCT, Ft as OSC11_RESPONSE_PREFIX_NO_ESC, G as getBreathingFrame, Gn as log, H as AgentGroupComponent, Hn as resolveScreamHome, Ht as isStreaming, I as getSharedSpeedTracker, In as PRODUCT_NAME, It as QUERY_TERMINAL_THEME, J as refineGoal, Jn as isOrphanedToolCallError, Jt as printableChar, K as resetBreathingClock, Kn as resolveGlobalLogPath, L as SkillActivationComponent, Ln as DEFAULT_CATALOG_URL, Lt as TERMINAL_FOCUS_IN, M as langFromPath, Mn as detectInstallSource, Mt as OSC11_QUERY, N as CachedContainer, Nn as CLI_COMMAND_NAME, Nt as OSC11_RESPONSE, O as ToolCallComponent, On as detectShellEnvironment, Ot as DISABLE_TERMINAL_FOCUS_REPORTING, P as ThinkingComponent, Pn as CLI_UI_MODE, Pt as OSC11_RESPONSE_PREFIX, Qt as formatErrorMessage, R as ReadGroupComponent, Rn as fetchCatalog, Rt as TERMINAL_FOCUS_OUT, S as getDaemonInstructions, Sn as PIXEL_PULSE_FRAMES, St as createMarkdownTheme, T as isEmptySessionHintDismissed, Tn as TuiLikePreferencesSchema, Tt as getColorPalette, U as WelcomeComponent, Un as MemoryMemoStore, Ut as FooterComponent, V as AssistantMessageComponent, Vt as isBusy, W as BREATHE_CYCLE_MS, Wn as flushDiagnosticLogs, Xn as SCREAM_ERROR_INFO, Xt as appendStreamingArgsPreview, Yn as ErrorCodes, Yt as STATUS_BULLET, Zt as argsRecord, _ as refreshUpdateCache, _n as isExperimentalFlagEnabled, _t as clearInfoPanelState, an as EMPTY_SESSION_HINT_URL, b as readJsonlFile, bn as isEmbeddingModelCached, bt as resolveThemeSync, c as hasDispose, cn as SESSION_TIPS, ct as handlePlanCommand, d as formatMemoryMemoForInjection, dn as getCtrlDHint, en as parseStreamingArgs, et as toTerminalHyperlink, fn as getLlmNotSetMessage, g as selectUpdateTarget, gn as sortSlashCommands, gt as supportsBalance, hn as BUILTIN_SLASH_COMMANDS, ht as refreshProviderBalance, i as buildRoleAdditionalText, in as CHARS_PER_TOKEN, j as highlightLines, jn as getLogDir, jt as ENABLE_TERMINAL_THEME_REPORTING, k as renderDiffLines, kn as getDataDir, kt as DISABLE_TERMINAL_THEME_REPORTING, l as isPlanExpandable, ln as TIP_ROTATION_INTERVAL_MS, mn as buildSkillSlashCommands, n as clearEvalPanelState, nn as stringValue, nt as getModelCycleLevel, on as EXIT_CONFIRM_WINDOW_MS, ot as handleFusionPlanCommand, pn as getNoActiveSessionMessage, q as clearGoalState, qn as isScreamError, r as openUrl, rn as truncateErrorMessage, s as disposeChildren, sn as MAIN_AGENT_ID, t as dispatchInput, tn as serializeToolResultOutput, tt as changeThinkingLevel, u as MoonLoader, un as getCtrlCHint, v as readUpdateCache, vn as setExperimentalFlags, w as UserMessageComponent, wn as TuiConfigParseError, wt as contrastTextHex, xn as startManualEmbeddingDownload, xt as createEditorTheme, y as appendJsonlLine, yn as getKnowledgeStore, z as parseReadGroupOutput, zn as saveCatalogCache, zt as TERMINAL_THEME_DARK } from "./dispatch-1ojfKMwf.mjs";
8
+ import { a as setLocale, o as t } from "./text-input-dialog-BUXAKycx.mjs";
9
9
  import { createRequire } from "node:module";
10
10
  import { randomUUID } from "node:crypto";
11
11
  import { access, mkdir, mkdtemp, readFile, readdir, realpath, rm, unlink, writeFile } from "node:fs/promises";
@@ -30,7 +30,7 @@ function optionalBuildString(value) {
30
30
  return typeof value === "string" && value.length > 0 ? value : void 0;
31
31
  }
32
32
  const SCREAM_BUILD_INFO = {
33
- version: optionalBuildString("0.14.8"),
33
+ version: optionalBuildString("0.14.9"),
34
34
  channel: optionalBuildString(""),
35
35
  commit: optionalBuildString(""),
36
36
  buildTarget: optionalBuildString("darwin-arm64")
@@ -797,18 +797,18 @@ var OnboardingCardComponent = class extends Container {
797
797
  const accent = chalk.hex(colors.accent);
798
798
  const lines = [];
799
799
  lines.push(leftPadText(leftPad, borderColor("┌" + "─".repeat(innerWidth) + "┐")));
800
- lines.push(leftPadText(leftPad, borderColor("│") + padInner("", innerWidth) + borderColor("│")));
801
- for (const descLine of wrapText$1(t("onboarding.description"), innerWidth)) lines.push(leftPadText(leftPad, borderColor("│") + padInner(descColor(descLine), innerWidth) + borderColor("│")));
802
- lines.push(leftPadText(leftPad, borderColor("│") + padInner("", innerWidth) + borderColor("│")));
800
+ lines.push(leftPadText(leftPad, borderColor("│") + padInner$1("", innerWidth) + borderColor("│")));
801
+ for (const descLine of wrapText$2(t("onboarding.description"), innerWidth)) lines.push(leftPadText(leftPad, borderColor("│") + padInner$1(descColor(descLine), innerWidth) + borderColor("│")));
802
+ lines.push(leftPadText(leftPad, borderColor("│") + padInner$1("", innerWidth) + borderColor("│")));
803
803
  for (let i = 0; i < this.actions.length; i++) {
804
804
  const action = this.actions[i];
805
805
  const selected = i === this.selectedIndex;
806
806
  const label = action === void 0 ? "" : action.label;
807
807
  const row = selected ? accent("▶ " + label) : descColor(" " + label);
808
- lines.push(leftPadText(leftPad, borderColor("│") + padInner(row, innerWidth) + borderColor("│")));
808
+ lines.push(leftPadText(leftPad, borderColor("│") + padInner$1(row, innerWidth) + borderColor("│")));
809
809
  }
810
- lines.push(leftPadText(leftPad, borderColor("│") + padInner("", innerWidth) + borderColor("│")));
811
- lines.push(leftPadText(leftPad, borderColor("│") + padInner(descColor(t("onboarding.hint")), innerWidth) + borderColor("│")));
810
+ lines.push(leftPadText(leftPad, borderColor("│") + padInner$1("", innerWidth) + borderColor("│")));
811
+ lines.push(leftPadText(leftPad, borderColor("│") + padInner$1(descColor(t("onboarding.hint")), innerWidth) + borderColor("│")));
812
812
  lines.push(leftPadText(leftPad, borderColor("└" + "─".repeat(innerWidth) + "┘")));
813
813
  const truncated = lines.map((line) => truncateToWidth(line, width));
814
814
  this.cachedWidth = width;
@@ -819,6 +819,104 @@ var OnboardingCardComponent = class extends Container {
819
819
  function leftPadText(pad, text) {
820
820
  return pad > 0 ? " ".repeat(pad) + text : text;
821
821
  }
822
+ function padInner$1(text, width) {
823
+ const vw = visibleWidth(text);
824
+ return text + " ".repeat(Math.max(0, width - vw));
825
+ }
826
+ function wrapText$2(text, width) {
827
+ const lines = [];
828
+ let current = "";
829
+ let currentWidth = 0;
830
+ for (const ch of text) {
831
+ const chWidth = visibleWidth(ch);
832
+ if (currentWidth + chWidth > width && currentWidth > 0) {
833
+ lines.push(current);
834
+ current = ch;
835
+ currentWidth = chWidth;
836
+ } else {
837
+ current += ch;
838
+ currentWidth += chWidth;
839
+ }
840
+ }
841
+ if (current.length > 0) lines.push(current);
842
+ return lines.length > 0 ? lines : [""];
843
+ }
844
+ //#endregion
845
+ //#region src/tui/components/dialogs/embedding-setup-card.ts
846
+ var EmbeddingSetupCardComponent = class extends Container {
847
+ focused = false;
848
+ opts;
849
+ selectedIndex = 0;
850
+ activated = false;
851
+ actions;
852
+ cachedWidth;
853
+ cachedLines;
854
+ constructor(opts) {
855
+ super();
856
+ this.opts = opts;
857
+ this.actions = [{
858
+ label: t("kw.setup_download"),
859
+ run: () => this.opts.onDownload()
860
+ }, {
861
+ label: t("kw.setup_skip"),
862
+ run: () => this.opts.onSkip()
863
+ }];
864
+ }
865
+ invalidate() {
866
+ this.cachedWidth = void 0;
867
+ this.cachedLines = void 0;
868
+ }
869
+ handleInput(data) {
870
+ if (this.activated) return;
871
+ if (matchesKey(data, Key.up)) {
872
+ this.selectedIndex = (this.selectedIndex + this.actions.length - 1) % this.actions.length;
873
+ this.invalidate();
874
+ return;
875
+ }
876
+ if (matchesKey(data, Key.down)) {
877
+ this.selectedIndex = (this.selectedIndex + 1) % this.actions.length;
878
+ this.invalidate();
879
+ return;
880
+ }
881
+ if (matchesKey(data, Key.enter) || matchesKey(data, Key.space)) {
882
+ this.activated = true;
883
+ const action = this.actions[this.selectedIndex];
884
+ if (action !== void 0) action.run();
885
+ return;
886
+ }
887
+ if (matchesKey(data, Key.escape) || matchesKey(data, Key.tab)) {
888
+ this.activated = true;
889
+ this.opts.onSkip();
890
+ }
891
+ }
892
+ render(width) {
893
+ if (this.cachedLines !== void 0 && this.cachedWidth === width) return this.cachedLines;
894
+ const { colors } = this.opts;
895
+ const innerWidth = Math.max(20, width) - 2;
896
+ const borderColor = chalk.hex(colors.primary);
897
+ const descColor = chalk.hex(colors.textDim);
898
+ const accent = chalk.hex(colors.accent);
899
+ const lines = [];
900
+ lines.push(borderColor("┌" + "─".repeat(innerWidth) + "┐"));
901
+ lines.push(borderColor("│") + padInner("", innerWidth) + borderColor("│"));
902
+ for (const descLine of wrapText$1(t("kw.setup_description"), innerWidth)) lines.push(borderColor("│") + padInner(descColor(descLine), innerWidth) + borderColor("│"));
903
+ lines.push(borderColor("│") + padInner("", innerWidth) + borderColor("│"));
904
+ for (let i = 0; i < this.actions.length; i++) {
905
+ const action = this.actions[i];
906
+ const selected = i === this.selectedIndex;
907
+ const label = action === void 0 ? "" : action.label;
908
+ const row = selected ? accent("▶ " + label) : descColor(" " + label);
909
+ lines.push(borderColor("│") + padInner(row, innerWidth) + borderColor("│"));
910
+ }
911
+ lines.push(borderColor("│") + padInner("", innerWidth) + borderColor("│"));
912
+ lines.push(borderColor("│") + padInner(descColor(t("kw.setup_hint")), innerWidth) + borderColor("│"));
913
+ lines.push(borderColor("└" + "─".repeat(innerWidth) + "┘"));
914
+ const truncated = lines.map((line) => truncateToWidth(line, width));
915
+ this.cachedWidth = width;
916
+ this.cachedLines = truncated;
917
+ return truncated;
918
+ }
919
+ };
822
920
  function padInner(text, width) {
823
921
  const vw = visibleWidth(text);
824
922
  return text + " ".repeat(Math.max(0, width - vw));
@@ -11923,7 +12021,8 @@ var ScreamTUI = class {
11923
12021
  this.state.editorContainer.clear();
11924
12022
  this.state.editorContainer.addChild(this.state.editor);
11925
12023
  this.state.ui.setFocus(this.state.editor);
11926
- if (!this.state.appState.model && this.state.startupState !== "picker") this.showOnboardingCard();
12024
+ if (!this.state.appState.model && this.state.startupState !== "picker") this.showOnboardingCard(() => void this.maybeShowEmbeddingSetup());
12025
+ else this.maybeShowEmbeddingSetup();
11927
12026
  return shouldReplayHistory;
11928
12027
  }
11929
12028
  /**
@@ -12247,18 +12346,71 @@ var ScreamTUI = class {
12247
12346
  this.transcriptController.renderWelcome();
12248
12347
  }
12249
12348
  /** First-run: no configured model → show the onboarding card (configure
12250
- * now / skip). Configure routes through the same /config connect flow. */
12251
- async showOnboardingCard() {
12349
+ * now / skip). Configure routes through the same /config connect flow.
12350
+ * `onDone` fires after the card is dismissed either way — used to chain
12351
+ * the embedding-model setup check so the two first-run cards never stack. */
12352
+ async showOnboardingCard(onDone) {
12252
12353
  try {
12253
- if (((await this.harness.getConfig({ reload: true })).defaultModel ?? "").trim().length > 0) return;
12354
+ if (((await this.harness.getConfig({ reload: true })).defaultModel ?? "").trim().length > 0) {
12355
+ onDone?.();
12356
+ return;
12357
+ }
12254
12358
  } catch {}
12255
12359
  const card = new OnboardingCardComponent({
12256
12360
  colors: this.state.theme.colors,
12257
12361
  onConfigure: () => {
12258
- import("./dispatch-DVJhr5Rj.mjs").then(({ handleConnectCommand }) => handleConnectCommand(this, "")).finally(() => {
12362
+ import("./dispatch-CJPpI4gm.mjs").then(({ handleConnectCommand }) => handleConnectCommand(this, "")).finally(() => {
12259
12363
  this.restoreEditor();
12364
+ onDone?.();
12260
12365
  });
12261
12366
  },
12367
+ onSkip: () => {
12368
+ this.restoreEditor();
12369
+ onDone?.();
12370
+ }
12371
+ });
12372
+ this.mountEditorReplacement(card);
12373
+ }
12374
+ /**
12375
+ * Post-onboarding embedding-model check. Cached model → warm the shared
12376
+ * engine in the background (local files only, no network); missing model →
12377
+ * surface a download card so /knowledge and /memory work on first try.
12378
+ */
12379
+ async maybeShowEmbeddingSetup() {
12380
+ if (this.state.startupState === "picker") return;
12381
+ try {
12382
+ await getKnowledgeStore();
12383
+ if (isEmbeddingModelCached()) {
12384
+ startManualEmbeddingDownload().catch(() => {});
12385
+ return;
12386
+ }
12387
+ } catch {
12388
+ return;
12389
+ }
12390
+ const card = new EmbeddingSetupCardComponent({
12391
+ colors: this.state.theme.colors,
12392
+ onDownload: () => {
12393
+ (async () => {
12394
+ this.restoreEditor();
12395
+ const spinner = this.showProgressSpinner(t("kw.embedding_downloading"));
12396
+ let ok = false;
12397
+ let error;
12398
+ try {
12399
+ ({ok, error} = await startManualEmbeddingDownload());
12400
+ } catch (error) {
12401
+ error = error instanceof Error ? error.message : String(error);
12402
+ }
12403
+ spinner.stop({
12404
+ ok,
12405
+ label: ok ? t("kw.embedding_ready") : t("kw.embedding_failed")
12406
+ });
12407
+ if (ok) this.showStatus(t("kw.embedding_ready"));
12408
+ else {
12409
+ const detail = [t("knowledge.download_model_retry_hint"), error].filter(Boolean).join("\n");
12410
+ this.showNotice(t("kw.embedding_failed"), detail);
12411
+ }
12412
+ })();
12413
+ },
12262
12414
  onSkip: () => {
12263
12415
  this.restoreEditor();
12264
12416
  }