dsh-neotui 0.1.16 → 0.1.18

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/package.json +1 -1
  2. package/src/views.js +17 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-neotui",
3
- "version": "0.1.16",
3
+ "version": "0.1.18",
4
4
  "description": "Neo-TUI: mouse-driven terminal UI client for DeepSeek Harness (B-tier per dsh-tui-design.md)",
5
5
  "type": "module",
6
6
  "bin": {
package/src/views.js CHANGED
@@ -233,7 +233,7 @@ function applyEvent(nodes, event, view, log, state = null) {
233
233
  if (!block) {
234
234
  // the callId did not match (missed tool/call in the loaded window):
235
235
  // attach to the most recent tool block still awaiting a result —
236
- // otherwise a SUCCESSFUL bash renders as a red "无结果" failure
236
+ // otherwise a SUCCESSFUL bash renders as a red failure label
237
237
  outer:
238
238
  for (let ni = nodes.length - 1; ni >= 0; ni--) {
239
239
  const nd = nodes[ni];
@@ -1301,9 +1301,14 @@ export class ChatView extends Widget {
1301
1301
  // whose result never matched (orphan) must freeze at 无结果 —
1302
1302
  // otherwise the timer runs forever ("timing chaos").
1303
1303
  const running = b.result == null && !b.done && node.streaming;
1304
+ // An ORPHAN = a finalized tool call whose result is absent from
1305
+ // the history (context compaction prunes old tool results, or
1306
+ // the result event never matched). It is NOT a failure and NOT
1307
+ // "the tool output nothing" — label it 结果未保留 to say what
1308
+ // it actually is.
1304
1309
  const orphan = b.result == null && !b.done && !node.streaming;
1305
- // An orphan (result never matched) is NOT a failure it renders
1306
- // neutral (◌, TOOLBG), never the red ✗ of a failed exit code.
1310
+ // An orphan renders neutral (◌, TOOLBG), never the red of a
1311
+ // failed exit code.
1307
1312
  const failed = !orphan && exitCode !== undefined && exitCode !== 0;
1308
1313
  const status = running ? "TOOLBG" : failed ? "TOOLERR" : "TOOLOK";
1309
1314
  const glyph = running ? "⏳" : failed ? "✗" : orphan ? "◌" : "✓";
@@ -1313,9 +1318,12 @@ export class ChatView extends Widget {
1313
1318
  if (running) {
1314
1319
  timing = ` 已经过 ${fmtDuration(Date.now() - (b.startedAt ?? Date.now()))}`;
1315
1320
  } else if (b.startedAt !== undefined && b.endedAt !== undefined) {
1316
- timing = ` ${failed ? "失败" : orphan ? "无结果" : "已完成"},耗时 ${fmtDuration(b.endedAt - b.startedAt)}`;
1321
+ // orphan note: the tool's own end timestamp was pruned WITH
1322
+ // its result, so endedAt here is the step-end stamp — the
1323
+ // duration is an upper bound, shown as ≤.
1324
+ timing = ` ${failed ? "失败" : orphan ? "结果未保留" : "已完成"},耗时 ${orphan ? "≤" : ""}${fmtDuration(b.endedAt - b.startedAt)}`;
1317
1325
  } else if (orphan) {
1318
- timing = " 无结果";
1326
+ timing = " 结果未保留";
1319
1327
  }
1320
1328
  lines.push([
1321
1329
  { t: open ? "▾ " : "▸ ", fg: K.ACCENT },
@@ -1343,6 +1351,10 @@ export class ChatView extends Widget {
1343
1351
  const rl = truncateText(b.result, 4000).split("\n");
1344
1352
  for (const r of rl.slice(0, 30)) { lines.push([{ t: " " + truncate(r, w - 4), fg: K.DIM }]); mark(realIdx, bi); }
1345
1353
  if (rl.length > 30) { lines.push([{ t: ` …共 ${rl.length} 行`, fg: K.FAINT }]); mark(realIdx, bi); }
1354
+ } else if (orphan) {
1355
+ // explain the ambiguous state instead of a bare 无结果
1356
+ lines.push([{ t: " 结果未保留:该工具调用的结果不在当前会话历史中(上下文压缩会修剪早期工具结果),并非执行失败或输出为空。", fg: K.FAINT }]);
1357
+ mark(realIdx, bi);
1346
1358
  }
1347
1359
  }
1348
1360
  sep();