dsh-neotui 0.0.14 → 0.0.15
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/package.json +1 -1
- package/src/views.js +21 -4
package/package.json
CHANGED
package/src/views.js
CHANGED
|
@@ -874,6 +874,12 @@ export class ChatView extends Widget {
|
|
|
874
874
|
if (first < 0) return;
|
|
875
875
|
const target = Math.min(first + topOffset, last);
|
|
876
876
|
this.view.scrollY = Math.max(0, Math.min(target, this.view.maxScroll()));
|
|
877
|
+
// never park the viewport on a blank separator row — it reads as a
|
|
878
|
+
// spurious offset right after the click
|
|
879
|
+
while (
|
|
880
|
+
this.view.scrollY < this.lineMap.length - 1 &&
|
|
881
|
+
!(this.lines[this.view.scrollY] ?? []).some((g) => g.t.trim() !== "")
|
|
882
|
+
) this.view.scrollY++;
|
|
877
883
|
};
|
|
878
884
|
if (node?.kind === "assistant" && info.blockIdx !== null) {
|
|
879
885
|
const b = node.blocks[info.blockIdx];
|
|
@@ -1016,12 +1022,16 @@ export class ChatView extends Widget {
|
|
|
1016
1022
|
const open = manuallyExpanded || (!manuallyCollapsed && this.thinkMode === "expanded");
|
|
1017
1023
|
beginCard("THINKBG");
|
|
1018
1024
|
// Live blocks tick (已经过…); finished blocks freeze at their
|
|
1019
|
-
// total (已完成,耗时…).
|
|
1025
|
+
// total (已完成,耗时…). Snapshot-derived blocks may lack a
|
|
1026
|
+
// per-block start (the history projection has no block-start):
|
|
1027
|
+
// show a plain 已完成 then — never a bogus ticking timer.
|
|
1020
1028
|
let timing = "";
|
|
1021
1029
|
if (b.streaming) {
|
|
1022
1030
|
timing = ` 已经过 ${fmtDuration(Date.now() - (b.startedAt ?? Date.now()))}`;
|
|
1023
1031
|
} else if (b.startedAt !== undefined && b.endedAt !== undefined) {
|
|
1024
1032
|
timing = ` 已完成,耗时 ${fmtDuration(b.endedAt - b.startedAt)}`;
|
|
1033
|
+
} else if (b.endedAt !== undefined) {
|
|
1034
|
+
timing = " 已完成";
|
|
1025
1035
|
}
|
|
1026
1036
|
const thinkMeta = `${stepTag}(${b.text?.length ?? 0} 字)${timing}`;
|
|
1027
1037
|
lines.push([{ t: "💭 思考" + (b.streaming ? "…" : "") + thinkMeta + (open ? " [t 折叠]" : " [t 展开]"), fg: K.FAINT }]);
|
|
@@ -1041,16 +1051,23 @@ export class ChatView extends Widget {
|
|
|
1041
1051
|
const key = `${realIdx}:${bi}`;
|
|
1042
1052
|
const open = this.bashMode !== "collapsed" && !this.collapsedBlocks.has(key);
|
|
1043
1053
|
const exitCode = b.view?.view?.exitCode;
|
|
1044
|
-
|
|
1045
|
-
|
|
1054
|
+
// A tool only TICKS while its turn is live. A finalized turn
|
|
1055
|
+
// whose result never matched (orphan) must freeze at 无结果 —
|
|
1056
|
+
// otherwise the timer runs forever ("timing chaos").
|
|
1057
|
+
const running = b.result == null && !b.done && node.streaming;
|
|
1058
|
+
const orphan = b.result == null && !b.done && !node.streaming;
|
|
1059
|
+
const status = orphan ? "TOOLERR" : running ? "TOOLBG" : exitCode !== undefined && exitCode !== 0 ? "TOOLERR" : "TOOLOK";
|
|
1060
|
+
const glyph = orphan ? "✗" : running ? "⏳" : exitCode !== undefined && exitCode !== 0 ? "✗" : "✓";
|
|
1046
1061
|
const card = b.view ? renderToolCard(b.view, w, open) : [];
|
|
1047
1062
|
beginCard(status);
|
|
1048
1063
|
let timing = "";
|
|
1049
|
-
if (
|
|
1064
|
+
if (running) {
|
|
1050
1065
|
timing = ` 已经过 ${fmtDuration(Date.now() - (b.startedAt ?? Date.now()))}`;
|
|
1051
1066
|
} else if (b.startedAt !== undefined && b.endedAt !== undefined) {
|
|
1052
1067
|
const failed = exitCode !== undefined && exitCode !== 0;
|
|
1053
1068
|
timing = ` ${failed ? "失败" : "已完成"},耗时 ${fmtDuration(b.endedAt - b.startedAt)}`;
|
|
1069
|
+
} else if (orphan) {
|
|
1070
|
+
timing = " 无结果";
|
|
1054
1071
|
}
|
|
1055
1072
|
lines.push([
|
|
1056
1073
|
{ t: open ? "▾ " : "▸ ", fg: K.ACCENT },
|