@yinan_chen/pi-claude-code-ui 0.8.1 → 0.8.4

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yinan_chen/pi-claude-code-ui",
3
- "version": "0.8.1",
3
+ "version": "0.8.4",
4
4
  "description": "Claude Code-style UI for Pi: transcript view, rich diffs, subagent panels and working-message status.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -3,6 +3,7 @@ import { Box, Container, Markdown, truncateToWidth, visibleWidth } from "@earend
3
3
  import { getMarkdownTheme, keyText } from "@earendil-works/pi-coding-agent";
4
4
  import { BUILTIN_NAMES, PROCESS_TOOL_NAMES, bold, canExpandTool, expandHint, failedTool, fg, fit, headerOf, isBlank, isImageLine, oneLine, paintBackground, paintTool, prefixed, prefixZones, resultIndent, RESULT_CONT, targetOf, type ToolAppearance, type ToolView } from "./claude-tools.ts";
5
5
  import { animateRunningSummary } from "./running-effect.ts";
6
+ import { normalizeForeignLines } from "./foreign-normalizer.ts";
6
7
 
7
8
  export interface ClaudeConfig extends ToolAppearance {
8
9
  detailsBackground: string;
@@ -727,7 +728,7 @@ export function createClaudeView(
727
728
  const api = {
728
729
  enabled: () => !disabled,
729
730
  fail, hookMode, renderChat, dispose,
730
- toolExecRender: (self: any, orig: Function, width: number) => renderTool(self, orig, width),
731
+ toolExecRender: (self: any, orig: Function, width: number) => normalizeForeignLines(renderTool(self, orig, width)),
731
732
  toolExecHandleMouse: (self: any, orig: Function, event: any) => disabled ? orig.call(self, event) : Container.prototype.handleMouse.call(self, event),
732
733
  assistantRender: renderAssistant,
733
734
  assistantUpdateContent(self: any, orig: Function, message: any, streaming?: boolean) {
@@ -28,6 +28,17 @@ function labelOf(customType: string): string {
28
28
  return tail.charAt(0).toUpperCase() + tail.slice(1);
29
29
  }
30
30
 
31
+ /** 预览首行:跳过空行与纯标点行({ } [ ] "),取首个有实质内容的行(截 120 列)。 */
32
+ function firstMeaningfulLine(lines: readonly string[]): string {
33
+ for (const line of lines) {
34
+ const text = oneLine(String(line)).trim();
35
+ if (text && !/^[{}\[\]",]*$/.test(text)) {
36
+ return text.length > 120 ? `${text.slice(0, 120)}…` : text;
37
+ }
38
+ }
39
+ return "(empty)";
40
+ }
41
+
31
42
  /** JSON 内容的智能首行:query/title 等字段优先,数组给条数,否则紧凑化。 */
32
43
  function jsonPreview(text: string): string | undefined {
33
44
  const trimmed = text.trim();
@@ -82,8 +93,13 @@ export function createGenericCardRenderer(hooks: GenericCardHooks) {
82
93
  if (expanded) {
83
94
  for (const line of visible) lines.push(...prefixed(fg(theme, "dim", line), width, first, RESULT_CONT()));
84
95
  } else {
85
- const head = oneLine(visible[0]);
86
- lines.push(...prefixed(fg(theme, "muted", head) + expandHint(theme), width, first, RESULT_CONT()));
96
+ // 与工具块/subagent 同构:首行预览独立一行,展开提示独立一行(… +N lines)。
97
+ const head = firstMeaningfulLine(visible);
98
+ lines.push(...prefixed(fg(theme, "muted", head), width, first, RESULT_CONT()));
99
+ if (visible.length > 1) {
100
+ const hidden = visible.length - 1;
101
+ lines.push(...prefixed(fg(theme, "dim", `… +${hidden} line${hidden === 1 ? "" : "s"}`) + expandHint(theme), width, first, RESULT_CONT()));
102
+ }
87
103
  }
88
104
  return lines;
89
105
  },