@crazyhappyone/dsh-tui 0.1.0-alpha.20 → 0.1.0-alpha.22

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.
Files changed (2) hide show
  1. package/dist/index.js +329 -87
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -47429,13 +47429,22 @@ function wcwidthSafeSlice(text4, maxCols) {
47429
47429
  }
47430
47430
  return text4.slice(0, end);
47431
47431
  }
47432
+ var NARROW_TO_WIDE_EMOJIS = {
47433
+ "\u26A0": "\u{1F6A8}",
47434
+ "\u2139": "\u{1F4A1}",
47435
+ "\u2699": "\u{1F527}",
47436
+ "\u23F1": "\u{23F0}",
47437
+ "\u2709": "\u{1F4E7}",
47438
+ "\u270F": "\u{1F4DD}"
47439
+ };
47432
47440
  function formatSymbolSpacing(text4) {
47433
47441
  if (text4 === "" || /^[\x20-\x7e]*$/u.test(text4)) return text4;
47434
- let res = text4.replace(/([\u26A0\u2699\u2139\u23F1\u2328\u2709\u270F\u2712\u2702\u26C8\u2764])(?!\uFE0F)/gu, "$1\uFE0F");
47435
- res = res.replace(/([\u2460-\u24F4\u2776-\u2793\u3251-\u325F\u32B1-\u32BF])([\u4E00-\u9FFF\u3400-\u4DBF])/gu, "$1 $2");
47436
- res = res.replace(/([\u4E00-\u9FFF\u3400-\u4DBF])([\u2460-\u24F4\u2776-\u2793\u3251-\u325F\u32B1-\u32BF])/gu, "$1 $2");
47437
- res = res.replace(/([\u{1F300}-\u{1FAFF}\u2600-\u27BF]\uFE0F?)([\u4E00-\u9FFF\u3400-\u4DBF])/gu, "$1 $2");
47438
- res = res.replace(/([\u4E00-\u9FFF\u3400-\u4DBF])([\u{1F300}-\u{1FAFF}\u2600-\u27BF])/gu, "$1 $2");
47442
+ let res = text4.replace(/([\u26A0\u2699\u2139\u23F1\u2709\u270F])[\uFE0E\uFE0F]?/gu, (_, ch) => NARROW_TO_WIDE_EMOJIS[ch] ?? ch);
47443
+ res = res.replace(/([\u2328\u2712\u2702\u26C8\u2764])(?!\uFE0F|\uFE0E)/gu, "$1\uFE0F");
47444
+ res = res.replace(/([\u2460-\u24F4\u2776-\u2793\u3251-\u325F\u32B1-\u32BF])([\u4E00-\u9FFF\u3400-\u4DBF\u3000-\u303F\uFF01-\uFF60])/gu, "$1 $2");
47445
+ res = res.replace(/([\u4E00-\u9FFF\u3400-\u4DBF\u3000-\u303F\uFF01-\uFF60])([\u2460-\u24F4\u2776-\u2793\u3251-\u325F\u32B1-\u32BF])/gu, "$1 $2");
47446
+ res = res.replace(/([\u{1F300}-\u{1FAFF}\u2600-\u27BF][\uFE0E\uFE0F]?)([\u4E00-\u9FFF\u3400-\u4DBF\u3000-\u303F\uFF01-\uFF60])/gu, "$1 $2");
47447
+ res = res.replace(/([\u4E00-\u9FFF\u3400-\u4DBF\u3000-\u303F\uFF01-\uFF60])([\u{1F300}-\u{1FAFF}\u2600-\u27BF])/gu, "$1 $2");
47439
47448
  return res;
47440
47449
  }
47441
47450
  function displayColumnSlice(text4, startCol, endCol) {
@@ -50016,8 +50025,26 @@ function blockPositionRange(node2) {
50016
50025
  function formatSeconds(ms) {
50017
50026
  return (ms / 1e3).toFixed(1);
50018
50027
  }
50019
- function thinkingHeader(durationMs, expanded) {
50020
- return paintRow([styled(`${expanded ? "\u25BE " : ""}\u273B \u601D\u8003 (${formatSeconds(durationMs)}s)`, "fgDim")]);
50028
+ var BRAILLE_SPINNER_FRAMES = [
50029
+ "\u280B",
50030
+ "\u2819",
50031
+ "\u2839",
50032
+ "\u2838",
50033
+ "\u283C",
50034
+ "\u2834",
50035
+ "\u2826",
50036
+ "\u2827",
50037
+ "\u2807",
50038
+ "\u280F"
50039
+ ];
50040
+ function getBrailleSpinnerFrame(liveMs) {
50041
+ const index = Math.floor(Math.max(0, liveMs ?? 0) / 100) % BRAILLE_SPINNER_FRAMES.length;
50042
+ return BRAILLE_SPINNER_FRAMES[index] ?? BRAILLE_SPINNER_FRAMES[0];
50043
+ }
50044
+ function thinkingHeader(durationMs, expanded, live = false) {
50045
+ const mark = expanded ? "\u25BE " : "";
50046
+ const icon = live ? getBrailleSpinnerFrame(durationMs) : "\u273B";
50047
+ return paintRow([styled(`${mark}${icon} \u601D\u8003 (${formatSeconds(durationMs)}s)`, "fgDim")]);
50021
50048
  }
50022
50049
  function bodyRow(line2, key) {
50023
50050
  return (0, import_jsx_runtime.jsx)(Text, { children: paintRow([styled(` ${escapeContent(line2)}`, "fgDim")]) }, key);
@@ -50029,7 +50056,7 @@ function ReasoningBlock({ text: text4, collapsed, durationMs, live = false, maxC
50029
50056
  return (0, import_jsx_runtime.jsxs)(Box_default, {
50030
50057
  flexDirection: "column",
50031
50058
  width: "100%",
50032
- children: [(0, import_jsx_runtime.jsx)(Text, { children: thinkingHeader(durationMs, !live) }), body.map((line2, index2) => bodyRow(line2, index2))]
50059
+ children: [(0, import_jsx_runtime.jsx)(Text, { children: thinkingHeader(durationMs, !live, live) }), body.map((line2, index2) => bodyRow(line2, index2))]
50033
50060
  });
50034
50061
  }
50035
50062
  function indexedRows(length, read) {
@@ -50200,18 +50227,9 @@ var dictionaries = {
50200
50227
  function tuiCopy(key, locale = "zh-CN") {
50201
50228
  return dictionaries[locale][key];
50202
50229
  }
50203
- var SWIMMING_FISH_FRAMES = [
50204
- ">o ",
50205
- " >o ",
50206
- " >o ",
50207
- " >o",
50208
- " >",
50209
- " ",
50210
- " \xB7 ",
50211
- "o "
50212
- ];
50230
+ var SWIMMING_FISH_FRAMES = BRAILLE_SPINNER_FRAMES;
50213
50231
  function getSwimmingFishFrame(liveMs) {
50214
- return SWIMMING_FISH_FRAMES[Math.floor(Math.max(0, liveMs ?? 0) / 150) % SWIMMING_FISH_FRAMES.length] ?? SWIMMING_FISH_FRAMES[0];
50232
+ return getBrailleSpinnerFrame(liveMs);
50215
50233
  }
50216
50234
  var GENERATION_TIPS_ZH = [
50217
50235
  "\u63D0\u793A\uFF1ACtrl+E \u5C55\u5F00\u5DE5\u5177\u5361 \xB7 /tools \u67E5\u770B\u5B8C\u6574\u8F93\u51FA",
@@ -53239,7 +53257,8 @@ function projectReasoningEntry(entry, scope) {
53239
53257
  sourceLength: entry.source.length,
53240
53258
  lines: []
53241
53259
  };
53242
- const lines = [lineForText(`${live ? "" : "\u25BE "}\u273B \u601D\u8003 (${secondsLabel}s)`, "fgDim", false, 0)];
53260
+ const icon = live ? getBrailleSpinnerFrame(reasoningDurationMs) : "\u273B";
53261
+ const lines = [lineForText(`${live ? "" : "\u25BE "}${icon} \u601D\u8003 (${secondsLabel}s)`, "fgDim", false, 0)];
53243
53262
  const body = wrapDisplayLines(escapeContent(entry.source), Math.max(1, scope.width - 4));
53244
53263
  for (const row of body) lines.push(lineForText(` ${row}`, "fgDim", false, lines.length));
53245
53264
  return {
@@ -55016,7 +55035,7 @@ function StreamView({ model, presenters, brandTier = "plain", brandAnimation = f
55016
55035
  id,
55017
55036
  kind: "active-placeholder",
55018
55037
  source: "",
55019
- meta: { activePlaceholder: `${getSwimmingFishFrame(liveMs)} \u25CF \u6B63\u5728\u5904\u7406\u2026 (${formatSeconds(liveMs)}s)` }
55038
+ meta: { activePlaceholder: `${getBrailleSpinnerFrame(liveMs)} \u25CF \u6B63\u5728\u5904\u7406\u2026 (${formatSeconds(liveMs)}s)` }
55020
55039
  }, blockRowsScope, void 0, true).lines,
55021
55040
  ranges: [],
55022
55041
  storeBlocks
@@ -55790,7 +55809,7 @@ function StreamView({ model, presenters, brandTier = "plain", brandAnimation = f
55790
55809
  const visibleParts = displayedParts(rawParts, reasoningExpanded);
55791
55810
  if (generating && visibleParts.length === 0) {
55792
55811
  const liveMs = liveDurationMs ?? turn.reasoningDurationMs;
55793
- const fish = getSwimmingFishFrame(liveMs);
55812
+ const fish = getBrailleSpinnerFrame(liveMs);
55794
55813
  const tip = getBilingualTip(liveMs, locale);
55795
55814
  return (0, import_jsx_runtime.jsxs)(Box_default, {
55796
55815
  flexDirection: "column",
@@ -56694,6 +56713,56 @@ function moveCaretByGrapheme(text4, caretIndex, direction) {
56694
56713
  for (const part of GRAPHEME.segment(text4.slice(caret))) return caret + part.segment.length;
56695
56714
  return text4.length;
56696
56715
  }
56716
+ function moveCaretUpLine(text4, caretIndex) {
56717
+ const lines = text4.split("\n");
56718
+ if (lines.length <= 1) return void 0;
56719
+ const caret = clampCaretIndex(text4, caretIndex);
56720
+ let accumulated = 0;
56721
+ let currentRow = 0;
56722
+ let col = 0;
56723
+ for (let r = 0; r < lines.length; r++) {
56724
+ const lineLen = lines[r].length;
56725
+ if (caret <= accumulated + lineLen) {
56726
+ currentRow = r;
56727
+ col = caret - accumulated;
56728
+ break;
56729
+ }
56730
+ accumulated += lineLen + 1;
56731
+ }
56732
+ if (currentRow === 0) return void 0;
56733
+ let targetAcc = 0;
56734
+ for (let r = 0; r < currentRow - 1; r++) {
56735
+ targetAcc += lines[r].length + 1;
56736
+ }
56737
+ const prevLineLen = lines[currentRow - 1].length;
56738
+ const targetCol = Math.min(col, prevLineLen);
56739
+ return targetAcc + targetCol;
56740
+ }
56741
+ function moveCaretDownLine(text4, caretIndex) {
56742
+ const lines = text4.split("\n");
56743
+ if (lines.length <= 1) return void 0;
56744
+ const caret = clampCaretIndex(text4, caretIndex);
56745
+ let accumulated = 0;
56746
+ let currentRow = lines.length - 1;
56747
+ let col = 0;
56748
+ for (let r = 0; r < lines.length; r++) {
56749
+ const lineLen = lines[r].length;
56750
+ if (caret <= accumulated + lineLen) {
56751
+ currentRow = r;
56752
+ col = caret - accumulated;
56753
+ break;
56754
+ }
56755
+ accumulated += lineLen + 1;
56756
+ }
56757
+ if (currentRow >= lines.length - 1) return void 0;
56758
+ let targetAcc = 0;
56759
+ for (let r = 0; r <= currentRow; r++) {
56760
+ targetAcc += lines[r].length + 1;
56761
+ }
56762
+ const nextLineLen = lines[currentRow + 1].length;
56763
+ const targetCol = Math.min(col, nextLineLen);
56764
+ return targetAcc + targetCol;
56765
+ }
56697
56766
  function composerFrameAnchor(text4, caretIndex, options) {
56698
56767
  const caret = composerCursorPosition(text4, caretIndex);
56699
56768
  const lineCount = Math.max(1, text4.split("\n").length);
@@ -57582,7 +57651,9 @@ function holdComposer(state, action) {
57582
57651
  mentionDismissed: state.mentionDismissed,
57583
57652
  commandSelectedIndex: state.commandSelectedIndex,
57584
57653
  commandDismissed: state.commandDismissed,
57585
- caretIndex: state.caretIndex
57654
+ caretIndex: state.caretIndex,
57655
+ historyIndex: state.historyIndex,
57656
+ historyDraft: state.historyDraft
57586
57657
  };
57587
57658
  }
57588
57659
  function draftKeyEffect(state, key, keyInfo, actions) {
@@ -57666,7 +57737,7 @@ function mapKeyEvent(state, key, keyInfo, commands, pane, search2, timeline = {
57666
57737
  candidateCount: 0,
57667
57738
  selectedIndex: 0,
57668
57739
  selectedCandidate: void 0
57669
- }, queuedDraft = {}, compaction = { available: false }) {
57740
+ }, queuedDraft = {}, compaction = { available: false }, inputHistory = []) {
57670
57741
  const commandMode = (state.commandQuery !== void 0 || state.text.startsWith("/")) && state.commandDismissed !== true;
57671
57742
  activeMentionQuery(state.text);
57672
57743
  const agentHubOpen = overlays.agentHub?.open === true;
@@ -57920,6 +57991,20 @@ function mapKeyEvent(state, key, keyInfo, commands, pane, search2, timeline = {
57920
57991
  prefixG: false,
57921
57992
  renaming: state.renaming
57922
57993
  };
57994
+ if (state.historyIndex !== void 0) {
57995
+ const restored = state.historyDraft ?? "";
57996
+ return {
57997
+ kind: "dispatch",
57998
+ action: { kind: "none" },
57999
+ text: restored,
58000
+ commandQuery: void 0,
58001
+ prefixG: false,
58002
+ renaming: state.renaming,
58003
+ caretIndex: restored.length,
58004
+ historyIndex: void 0,
58005
+ historyDraft: void 0
58006
+ };
58007
+ }
57923
58008
  return {
57924
58009
  kind: "dispatch",
57925
58010
  action: { kind: "none" },
@@ -58102,7 +58187,9 @@ function mapKeyEvent(state, key, keyInfo, commands, pane, search2, timeline = {
58102
58187
  mentionDismissed: false,
58103
58188
  commandSelectedIndex: 0,
58104
58189
  commandDismissed: false,
58105
- caretIndex: previous3
58190
+ caretIndex: previous3,
58191
+ historyIndex: state.historyIndex,
58192
+ historyDraft: state.historyDraft
58106
58193
  };
58107
58194
  }
58108
58195
  if ((key === " " || keyInfo.tab) && keyInfo.shift) {
@@ -58504,7 +58591,9 @@ function mapKeyEvent(state, key, keyInfo, commands, pane, search2, timeline = {
58504
58591
  commandQuery: state.commandQuery,
58505
58592
  prefixG: false,
58506
58593
  renaming: state.renaming,
58507
- caretIndex: moveCaretByGrapheme(state.text, caret, keyInfo.leftArrow ? -1 : 1)
58594
+ caretIndex: moveCaretByGrapheme(state.text, caret, keyInfo.leftArrow ? -1 : 1),
58595
+ historyIndex: state.historyIndex,
58596
+ historyDraft: state.historyDraft
58508
58597
  };
58509
58598
  }
58510
58599
  if (keyInfo.pageUp) return holdComposer(state, {
@@ -58524,6 +58613,21 @@ function mapKeyEvent(state, key, keyInfo, commands, pane, search2, timeline = {
58524
58613
  edge: "latest"
58525
58614
  });
58526
58615
  if (keyInfo.upArrow) {
58616
+ if (state.text.includes("\n")) {
58617
+ const caret = clampCaretIndex(state.text, state.caretIndex);
58618
+ const targetCaret = moveCaretUpLine(state.text, caret);
58619
+ if (targetCaret !== void 0) return {
58620
+ kind: "dispatch",
58621
+ action: { kind: "none" },
58622
+ text: state.text,
58623
+ commandQuery: state.commandQuery,
58624
+ prefixG: false,
58625
+ renaming: state.renaming,
58626
+ caretIndex: targetCaret,
58627
+ historyIndex: state.historyIndex,
58628
+ historyDraft: state.historyDraft
58629
+ };
58630
+ }
58527
58631
  if (state.text === "" && queuedDraft.headText !== void 0) return {
58528
58632
  kind: "dispatch",
58529
58633
  action: { kind: "take-queued-draft" },
@@ -58531,33 +58635,77 @@ function mapKeyEvent(state, key, keyInfo, commands, pane, search2, timeline = {
58531
58635
  commandQuery: void 0,
58532
58636
  prefixG: false,
58533
58637
  renaming: state.renaming,
58534
- caretIndex: queuedDraft.headText.length
58535
- };
58536
- return {
58537
- kind: "dispatch",
58538
- action: {
58539
- kind: "scroll",
58540
- delta: 1
58541
- },
58542
- text: state.text,
58543
- commandQuery: state.commandQuery,
58544
- prefixG: false,
58545
- renaming: state.renaming,
58546
- caretIndex: state.caretIndex
58547
- };
58638
+ caretIndex: queuedDraft.headText.length,
58639
+ historyIndex: void 0,
58640
+ historyDraft: void 0
58641
+ };
58642
+ if (inputHistory.length > 0) {
58643
+ const isBrowsing = state.historyIndex !== void 0;
58644
+ const currentIndex = state.historyIndex ?? inputHistory.length;
58645
+ const nextIndex = Math.max(0, currentIndex - 1);
58646
+ const nextText = inputHistory[nextIndex] ?? "";
58647
+ const savedDraft = isBrowsing ? state.historyDraft : state.text;
58648
+ return {
58649
+ kind: "dispatch",
58650
+ action: { kind: "none" },
58651
+ text: nextText,
58652
+ commandQuery: void 0,
58653
+ prefixG: false,
58654
+ renaming: state.renaming,
58655
+ caretIndex: nextText.length,
58656
+ historyIndex: nextIndex,
58657
+ historyDraft: savedDraft
58658
+ };
58659
+ }
58660
+ return { kind: "none" };
58661
+ }
58662
+ if (keyInfo.downArrow) {
58663
+ if (state.text.includes("\n")) {
58664
+ const caret = clampCaretIndex(state.text, state.caretIndex);
58665
+ const targetCaret = moveCaretDownLine(state.text, caret);
58666
+ if (targetCaret !== void 0) return {
58667
+ kind: "dispatch",
58668
+ action: { kind: "none" },
58669
+ text: state.text,
58670
+ commandQuery: state.commandQuery,
58671
+ prefixG: false,
58672
+ renaming: state.renaming,
58673
+ caretIndex: targetCaret,
58674
+ historyIndex: state.historyIndex,
58675
+ historyDraft: state.historyDraft
58676
+ };
58677
+ }
58678
+ if (state.historyIndex !== void 0) {
58679
+ const nextIndex = state.historyIndex + 1;
58680
+ if (nextIndex < inputHistory.length) {
58681
+ const nextText = inputHistory[nextIndex] ?? "";
58682
+ return {
58683
+ kind: "dispatch",
58684
+ action: { kind: "none" },
58685
+ text: nextText,
58686
+ commandQuery: void 0,
58687
+ prefixG: false,
58688
+ renaming: state.renaming,
58689
+ caretIndex: nextText.length,
58690
+ historyIndex: nextIndex,
58691
+ historyDraft: state.historyDraft
58692
+ };
58693
+ }
58694
+ const restored = state.historyDraft ?? "";
58695
+ return {
58696
+ kind: "dispatch",
58697
+ action: { kind: "none" },
58698
+ text: restored,
58699
+ commandQuery: void 0,
58700
+ prefixG: false,
58701
+ renaming: state.renaming,
58702
+ caretIndex: restored.length,
58703
+ historyIndex: void 0,
58704
+ historyDraft: void 0
58705
+ };
58706
+ }
58707
+ return { kind: "none" };
58548
58708
  }
58549
- if (keyInfo.downArrow) return {
58550
- kind: "dispatch",
58551
- action: {
58552
- kind: "scroll",
58553
- delta: -1
58554
- },
58555
- text: state.text,
58556
- commandQuery: state.commandQuery,
58557
- prefixG: false,
58558
- renaming: state.renaming,
58559
- caretIndex: state.caretIndex
58560
- };
58561
58709
  if (/^[jk]+$/u.test(key) && !keyInfo.ctrl && !keyInfo.meta && state.text === "") {
58562
58710
  let delta = 0;
58563
58711
  for (const char of key) if (char === "k") delta += 1;
@@ -58591,7 +58739,9 @@ function mapKeyEvent(state, key, keyInfo, commands, pane, search2, timeline = {
58591
58739
  renaming: state.renaming,
58592
58740
  caretIndex: caret + 1,
58593
58741
  commandSelectedIndex: 0,
58594
- commandDismissed: false
58742
+ commandDismissed: false,
58743
+ historyIndex: state.historyIndex,
58744
+ historyDraft: state.historyDraft
58595
58745
  };
58596
58746
  }
58597
58747
  if (key === "@") {
@@ -58607,7 +58757,9 @@ function mapKeyEvent(state, key, keyInfo, commands, pane, search2, timeline = {
58607
58757
  mentionDismissed: false,
58608
58758
  commandSelectedIndex: 0,
58609
58759
  commandDismissed: false,
58610
- caretIndex: caret + 1
58760
+ caretIndex: caret + 1,
58761
+ historyIndex: state.historyIndex,
58762
+ historyDraft: state.historyDraft
58611
58763
  };
58612
58764
  }
58613
58765
  if (isTextInput(key, keyInfo)) {
@@ -58624,7 +58776,9 @@ function mapKeyEvent(state, key, keyInfo, commands, pane, search2, timeline = {
58624
58776
  mentionDismissed: false,
58625
58777
  commandSelectedIndex: 0,
58626
58778
  commandDismissed: false,
58627
- caretIndex: caret + key.length
58779
+ caretIndex: caret + key.length,
58780
+ historyIndex: state.historyIndex,
58781
+ historyDraft: state.historyDraft
58628
58782
  };
58629
58783
  }
58630
58784
  return {
@@ -58633,7 +58787,9 @@ function mapKeyEvent(state, key, keyInfo, commands, pane, search2, timeline = {
58633
58787
  text: state.text,
58634
58788
  commandQuery: state.commandQuery,
58635
58789
  prefixG: false,
58636
- renaming: state.renaming
58790
+ renaming: state.renaming,
58791
+ historyIndex: state.historyIndex,
58792
+ historyDraft: state.historyDraft
58637
58793
  };
58638
58794
  }
58639
58795
  function feedbackLabel(feedback) {
@@ -58796,6 +58952,20 @@ function TuiLoop({ title, controller, brandTier = "plain", brandAutoEligible = f
58796
58952
  helpLinesRef.current = helpPane.lines;
58797
58953
  const historyLengthRef = (0, import_react34.useRef)(model.history.length);
58798
58954
  historyLengthRef.current = model.history.length;
58955
+ const sentHistoryRef = (0, import_react34.useRef)([]);
58956
+ const inputHistory = (0, import_react34.useMemo)(() => {
58957
+ const fromModel = model.history
58958
+ .filter((m) => m.kind === "user" && typeof m.text === "string" && m.text.trim().length > 0)
58959
+ .map((m) => m.text);
58960
+ const combined = [];
58961
+ for (const item of [...fromModel, ...sentHistoryRef.current]) {
58962
+ const trimmed = item.trim();
58963
+ if (trimmed.length > 0 && combined.at(-1) !== trimmed) {
58964
+ combined.push(trimmed);
58965
+ }
58966
+ }
58967
+ return combined;
58968
+ }, [model.history]);
58799
58969
  const chordTimerRef = (0, import_react34.useRef)(void 0);
58800
58970
  const clearChord = () => {
58801
58971
  if (chordTimerRef.current !== void 0) {
@@ -58910,7 +59080,7 @@ function TuiLoop({ title, controller, brandTier = "plain", brandAutoEligible = f
58910
59080
  candidateCount: mentionCandidates.length,
58911
59081
  selectedIndex: current.mentionSelectedIndex,
58912
59082
  selectedCandidate: mentionCandidates[current.mentionSelectedIndex]
58913
- }, { headText: queuedDraftText }, { available: (model.compactionDividers?.length ?? 0) > 0 });
59083
+ }, { headText: queuedDraftText }, { available: (model.compactionDividers?.length ?? 0) > 0 }, inputHistory);
58914
59084
  if (effect.kind === "dispatch") {
58915
59085
  const action = effect.action;
58916
59086
  if (isSessionTransitionAction(action) && isSessionTransitionStatus(feedbackRef.current)) {
@@ -58936,7 +59106,21 @@ function TuiLoop({ title, controller, brandTier = "plain", brandAutoEligible = f
58936
59106
  kind: "edge",
58937
59107
  edge: action.edge
58938
59108
  });
58939
- else if (action.kind === "send" || action.kind === "new-session" || action.kind === "select-session") {
59109
+ else if (action.kind === "send") {
59110
+ const trimmed = action.text.trim();
59111
+ if (trimmed.length > 0 && sentHistoryRef.current.at(-1) !== trimmed) {
59112
+ sentHistoryRef.current.push(trimmed);
59113
+ }
59114
+ issueViewportCommand({ kind: "reset" });
59115
+ controller.dispatch(action);
59116
+ } else if (action.kind === "command") {
59117
+ const queryText = action.query.trim().startsWith("/") ? action.query.trim() : `/${action.query.trim()}`;
59118
+ if (queryText.length > 0 && sentHistoryRef.current.at(-1) !== queryText) {
59119
+ sentHistoryRef.current.push(queryText);
59120
+ }
59121
+ controller.dispatch(action);
59122
+ } else if (action.kind === "new-session" || action.kind === "select-session") {
59123
+ sentHistoryRef.current = [];
58940
59124
  issueViewportCommand({ kind: "reset" });
58941
59125
  controller.dispatch(action);
58942
59126
  } else if (action.kind === "intake-clipboard-image") controller.intakeClipboardImage().then((result) => {
@@ -58966,7 +59150,9 @@ function TuiLoop({ title, controller, brandTier = "plain", brandAutoEligible = f
58966
59150
  mentionDismissed: effect.mentionDismissed ?? current.mentionDismissed,
58967
59151
  commandSelectedIndex: effect.commandSelectedIndex ?? current.commandSelectedIndex,
58968
59152
  commandDismissed: effect.commandDismissed ?? current.commandDismissed,
58969
- caretIndex: effect.caretIndex ?? (effect.text === current.text ? current.caretIndex : void 0)
59153
+ caretIndex: effect.caretIndex ?? (effect.text === current.text ? current.caretIndex : void 0),
59154
+ historyIndex: effect.historyIndex,
59155
+ historyDraft: effect.historyDraft
58970
59156
  } : current;
58971
59157
  stateRef.current = next;
58972
59158
  setState(next);
@@ -58982,7 +59168,9 @@ function TuiLoop({ title, controller, brandTier = "plain", brandAutoEligible = f
58982
59168
  mentionDismissed: false,
58983
59169
  commandSelectedIndex: 0,
58984
59170
  commandDismissed: false,
58985
- caretIndex: caret + token.length
59171
+ caretIndex: caret + token.length,
59172
+ historyIndex: void 0,
59173
+ historyDraft: void 0
58986
59174
  };
58987
59175
  stateRef.current = next;
58988
59176
  setState(next);
@@ -59023,7 +59211,9 @@ function TuiLoop({ title, controller, brandTier = "plain", brandAutoEligible = f
59023
59211
  mentionDismissed: false,
59024
59212
  commandSelectedIndex: 0,
59025
59213
  commandDismissed: false,
59026
- caretIndex: caret + pasted.length
59214
+ caretIndex: caret + pasted.length,
59215
+ historyIndex: void 0,
59216
+ historyDraft: void 0
59027
59217
  };
59028
59218
  stateRef.current = next;
59029
59219
  setState(next);
@@ -63406,6 +63596,7 @@ var RuntimeController = class _RuntimeController {
63406
63596
  }
63407
63597
  if (!this.deleteCapable()) {
63408
63598
  this.deleteUnavailable = true;
63599
+ this.setFeedback("\u2139 \u5F53\u524D\u4F1A\u8BDD\u5B58\u50A8\u4E3A\u53EA\u8FFD\u52A0\u65E5\u5FD7\uFF0C\u4E0D\u652F\u6301\u7269\u7406\u5220\u9664");
63409
63600
  this.emit();
63410
63601
  return;
63411
63602
  }
@@ -64207,9 +64398,13 @@ var RuntimeController = class _RuntimeController {
64207
64398
  try {
64208
64399
  const items = await persistence.list();
64209
64400
  const liveSession = this.session;
64401
+ const interactiveItems = items.filter((item) => {
64402
+ const header = item.header ?? item;
64403
+ return header.origin !== "subagent" && header.parentSession === void 0;
64404
+ });
64210
64405
  const listedIds = /* @__PURE__ */ new Set();
64211
64406
  const uncached = [];
64212
- for (const item of items) {
64407
+ for (const item of interactiveItems) {
64213
64408
  const header = item.header ?? item;
64214
64409
  const id = header.id;
64215
64410
  listedIds.add(id);
@@ -64228,6 +64423,40 @@ var RuntimeController = class _RuntimeController {
64228
64423
  this.sessionRowCache.delete(id);
64229
64424
  }
64230
64425
  }
64426
+ const initialRows = [];
64427
+ for (const item of interactiveItems) {
64428
+ const header = item.header ?? item;
64429
+ const id = header.id;
64430
+ if (liveSession !== void 0 && liveSession.id === id) {
64431
+ initialRows.push(this.rowForLiveSession(liveSession));
64432
+ } else {
64433
+ const cached = this.sessionRowCache.get(id);
64434
+ if (cached !== void 0) {
64435
+ initialRows.push(cached.row);
64436
+ } else {
64437
+ initialRows.push({
64438
+ id,
64439
+ title: id,
64440
+ updatedAt: header.createdAt ?? 0
64441
+ });
64442
+ }
64443
+ }
64444
+ }
64445
+ if (this.session !== void 0 && !initialRows.some((row) => row.id === this.session?.id)) {
64446
+ initialRows.push(this.rowForLiveSession(this.session));
64447
+ }
64448
+ initialRows.sort((a, b) => b.updatedAt - a.updatedAt);
64449
+ if (this.closed) return;
64450
+ this.sessionList = initialRows;
64451
+ if (preferredId !== void 0) {
64452
+ const preferredIndex2 = initialRows.findIndex((row) => row.id === preferredId);
64453
+ if (preferredIndex2 >= 0) {
64454
+ this.selectedIndex = preferredIndex2;
64455
+ }
64456
+ } else if (this.selectedIndex >= initialRows.length) {
64457
+ this.selectedIndex = Math.max(0, initialRows.length - 1);
64458
+ }
64459
+ this.emit();
64231
64460
  if (uncached.length > 0) {
64232
64461
  const BATCH_SIZE = 16;
64233
64462
  for (let i = 0; i < uncached.length; i += BATCH_SIZE) {
@@ -64242,35 +64471,48 @@ var RuntimeController = class _RuntimeController {
64242
64471
  for (const entry of fetched) {
64243
64472
  this.sessionRowCache.set(entry.id, { row: entry.row, revision: entry.revision });
64244
64473
  }
64245
- }
64246
- }
64247
- if (this.closed) return;
64248
- const rows = [];
64249
- for (const item of items) {
64250
- const header = item.header ?? item;
64251
- const id = header.id;
64252
- if (liveSession !== void 0 && liveSession.id === id) {
64253
- rows.push(this.rowForLiveSession(liveSession));
64254
- } else {
64255
- const cached = this.sessionRowCache.get(id);
64256
- if (cached !== void 0) {
64257
- rows.push(cached.row);
64258
- } else {
64259
- rows.push(await this.rowFor(id));
64474
+ if (!this.closed) {
64475
+ const updatedRows = [];
64476
+ for (const item of interactiveItems) {
64477
+ const header = item.header ?? item;
64478
+ const id = header.id;
64479
+ if (liveSession !== void 0 && liveSession.id === id) {
64480
+ updatedRows.push(this.rowForLiveSession(liveSession));
64481
+ } else {
64482
+ const cached = this.sessionRowCache.get(id);
64483
+ if (cached !== void 0) {
64484
+ updatedRows.push(cached.row);
64485
+ } else {
64486
+ updatedRows.push({
64487
+ id,
64488
+ title: id,
64489
+ updatedAt: header.createdAt ?? 0
64490
+ });
64491
+ }
64492
+ }
64493
+ }
64494
+ if (this.session !== void 0 && !updatedRows.some((row) => row.id === this.session?.id)) {
64495
+ updatedRows.push(this.rowForLiveSession(this.session));
64496
+ }
64497
+ updatedRows.sort((a, b) => b.updatedAt - a.updatedAt);
64498
+ this.sessionList = updatedRows;
64499
+ if (preferredId !== void 0) {
64500
+ const preferredIndex2 = updatedRows.findIndex((row) => row.id === preferredId);
64501
+ if (preferredIndex2 >= 0) {
64502
+ this.selectedIndex = preferredIndex2;
64503
+ }
64504
+ } else if (this.selectedIndex >= updatedRows.length) {
64505
+ this.selectedIndex = Math.max(0, updatedRows.length - 1);
64506
+ }
64507
+ this.emit();
64260
64508
  }
64261
64509
  }
64262
64510
  }
64263
- if (this.session !== void 0 && !rows.some((row) => row.id === this.session?.id)) {
64264
- rows.push(this.rowForLiveSession(this.session));
64265
- }
64266
- rows.sort((a, b) => b.updatedAt - a.updatedAt);
64267
- if (this.closed) return;
64268
- this.sessionList = rows;
64269
- const preferredIndex = preferredId === void 0 ? -1 : rows.findIndex((row) => row.id === preferredId);
64511
+ const preferredIndex = preferredId === void 0 ? -1 : this.sessionList.findIndex((row) => row.id === preferredId);
64270
64512
  if (preferredIndex >= 0) {
64271
64513
  this.selectedIndex = preferredIndex;
64272
- } else if (this.selectedIndex >= rows.length) {
64273
- this.selectedIndex = Math.max(0, rows.length - 1);
64514
+ } else if (this.selectedIndex >= this.sessionList.length) {
64515
+ this.selectedIndex = Math.max(0, this.sessionList.length - 1);
64274
64516
  }
64275
64517
  this.confirmDelete = false;
64276
64518
  this.emit();
@@ -64316,7 +64558,7 @@ var RuntimeController = class _RuntimeController {
64316
64558
  updatedAt: events.at(-1)?.time ?? createdAt
64317
64559
  };
64318
64560
  } catch {
64319
- return { id, title: id, updatedAt: Date.now() };
64561
+ return { id, title: id, updatedAt: 0 };
64320
64562
  }
64321
64563
  }
64322
64564
  /** Queue the newest query and enter loading before its debounce delay. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crazyhappyone/dsh-tui",
3
- "version": "0.1.0-alpha.20",
3
+ "version": "0.1.0-alpha.22",
4
4
  "description": "Source-runtime launcher for the DeepSeek Harness terminal interface",
5
5
  "type": "module",
6
6
  "license": "MIT",