pi-cc-extensions 0.8.50 → 0.8.51

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.
@@ -163,12 +163,7 @@ export function normalizeConfig(input: unknown): Config {
163
163
  DEFAULT_CONFIG.animationIntervalMs,
164
164
  ),
165
165
  showStartupHeader: source.showStartupHeader !== false,
166
- scrollStepLines: pickPositiveInt(
167
- source.scrollStepLines,
168
- DEFAULT_CONFIG.scrollStepLines,
169
- 1,
170
- 50,
171
- ),
166
+ scrollStepLines: pickPositiveInt(source.scrollStepLines, DEFAULT_CONFIG.scrollStepLines, 1, 50),
172
167
  };
173
168
  }
174
169
 
@@ -348,12 +348,7 @@ export async function showCcstylePanel(
348
348
  applyStartupHeader(ctx);
349
349
  break;
350
350
  case "scrollStepLines":
351
- config.scrollStepLines = pickPositiveInt(
352
- value,
353
- DEFAULT_CONFIG.scrollStepLines,
354
- 1,
355
- 50,
356
- );
351
+ config.scrollStepLines = pickPositiveInt(value, DEFAULT_CONFIG.scrollStepLines, 1, 50);
357
352
  break;
358
353
  default:
359
354
  return;
@@ -19,14 +19,14 @@ import {
19
19
  export const AGENT_SUMMARY_ENTRY_TYPE = "agent-summary";
20
20
 
21
21
  export default function (pi: ExtensionAPI): void {
22
- pi.registerEntryRenderer<AgentSummaryData>(
23
- AGENT_SUMMARY_ENTRY_TYPE,
24
- (entry, _options, _theme) => {
25
- const line = summaryMarkdown(entry.data, true);
26
- if (!line) return undefined;
27
- return new Markdown(line, 1, 0, getMarkdownTheme());
28
- },
29
- );
22
+ pi.registerEntryRenderer<AgentSummaryData>(AGENT_SUMMARY_ENTRY_TYPE, (entry, _options, theme) => {
23
+ const line = summaryMarkdown(entry.data, true, {
24
+ success: theme.getFgAnsi("success"),
25
+ failed: theme.getFgAnsi("error"),
26
+ });
27
+ if (!line) return undefined;
28
+ return new Markdown(line, 1, 0, getMarkdownTheme());
29
+ });
30
30
 
31
31
  bindAgentSummary(pi, (data) => {
32
32
  pi.appendEntry(AGENT_SUMMARY_ENTRY_TYPE, data);
@@ -363,13 +363,13 @@ function compactThinking(pi: ExtensionAPI) {
363
363
  const content = message.content[i];
364
364
 
365
365
  if (content.type === "text" && content.text.trim()) {
366
- self.contentContainer.addChild(
367
- new Markdown(content.text.trim(), self.outputPad, 0, self.markdownTheme, undefined, {
368
- transform: createTransform("assistant", self),
369
- }),
370
- );
371
- continue;
372
- }
366
+ self.contentContainer.addChild(
367
+ new Markdown(content.text.trim(), self.outputPad, 0, self.markdownTheme, undefined, {
368
+ transform: createTransform("assistant", self),
369
+ }),
370
+ );
371
+ continue;
372
+ }
373
373
 
374
374
  if (content.type !== "thinking") continue;
375
375
 
@@ -170,7 +170,10 @@ function getArt(src: string): ReturnType<typeof renderMermaid> | null {
170
170
  }
171
171
 
172
172
  /** Mermaid 方言代码块 → ASCII 图(流式跳过)。 */
173
- function renderDiagrams(markdown: string, context?: { isStreaming?: boolean; availableWidth?: number }): string {
173
+ function renderDiagrams(
174
+ markdown: string,
175
+ context?: { isStreaming?: boolean; availableWidth?: number },
176
+ ): string {
174
177
  const { isStreaming = false, availableWidth } = context ?? {};
175
178
  if (isStreaming) return markdown;
176
179
  const lines = markdown.split("\n");
@@ -15,13 +15,7 @@ const ANSI_PATTERN =
15
15
 
16
16
  // 官方 install.sh 静态 logo(4 行原样,短行补尾随空格统一到 8 列)+ 底部空行补到 5 行,
17
17
  // 与右侧 tips 行数等高;着色保持现状(accent 渐变)
18
- const LOGO_LINES = [
19
- "██████ ",
20
- "██ ██ ",
21
- "████ ██",
22
- "██ ██",
23
- " ",
24
- ];
18
+ const LOGO_LINES = ["██████ ", "██ ██ ", "████ ██", "██ ██", " "];
25
19
 
26
20
  // hero 文案(单行,替换原生 header 的 "Pi can explain..." 默认位置)
27
21
  const HERO_PREFIX = "There are many agent harnesses, but this one is ";
@@ -325,7 +319,8 @@ export function renderHeaderLines(
325
319
  ];
326
320
 
327
321
  return paddedLeft.map(
328
- (line, index) => `${line}${" ".repeat(TWO_COL_GAP)}${fitLineToWidth(rightLines[index] ?? "", rightWidth)}`,
322
+ (line, index) =>
323
+ `${line}${" ".repeat(TWO_COL_GAP)}${fitLineToWidth(rightLines[index] ?? "", rightWidth)}`,
329
324
  );
330
325
  }
331
326
 
@@ -45,7 +45,8 @@ const SKILL_KIND: DisplayKind = {
45
45
  };
46
46
 
47
47
  const COMPACTION_KIND: DisplayKind = {
48
- title: (component) => `Compacted from ${Number(component.message?.tokensBefore ?? 0).toLocaleString()} tokens`,
48
+ title: (component) =>
49
+ `Compacted from ${Number(component.message?.tokensBefore ?? 0).toLocaleString()} tokens`,
49
50
  body: (component) => String(component.message?.summary ?? ""),
50
51
  };
51
52
 
@@ -58,6 +59,10 @@ function renderCcstyle(component: any, kind: DisplayKind): void {
58
59
  const theme = displayTheme;
59
60
  if (!theme) return; // 主题未就绪时保留原生渲染
60
61
  if (component.bgFn) component.setBgFn?.(undefined); // 与工具调用一致,去掉灰底
62
+ if (component.paddingY !== 0) {
63
+ component._ccstyleOriginalPaddingY = component.paddingY;
64
+ component.paddingY = 0; // 工具组件 paddingY=0;原生 Box 默认 1,会上下各留一个空行
65
+ }
61
66
  component.clear();
62
67
  const icon = `${BRIGHT_GREEN}✓${ANSI_FG_RESET}`; // 已完成消息,等同工具成功态
63
68
  const title = theme.fg("toolTitle", kind.title(component));
@@ -75,7 +80,11 @@ function renderCcstyle(component: any, kind: DisplayKind): void {
75
80
  );
76
81
  }
77
82
 
78
- type PatchEntry = { prototype: any; installed: (...args: any[]) => void; original: (...args: any[]) => void };
83
+ type PatchEntry = {
84
+ prototype: any;
85
+ installed: (...args: any[]) => void;
86
+ original: (...args: any[]) => void;
87
+ };
79
88
 
80
89
  /** patch 三个消息组件的 updateDisplay,返回统一 dispose(/reload 链安全)。 */
81
90
  export function installMessageDisplayRendering(): () => void {
@@ -99,6 +108,11 @@ export function installMessageDisplayRendering(): () => void {
99
108
  // 渲染失败回退原生
100
109
  }
101
110
  }
111
+ // 回退原生前恢复 paddingY,避免原生渲染丢失上下内边距
112
+ if (this._ccstyleOriginalPaddingY !== undefined) {
113
+ this.paddingY = this._ccstyleOriginalPaddingY;
114
+ delete this._ccstyleOriginalPaddingY;
115
+ }
102
116
  original.call(this);
103
117
  };
104
118
  prototype.updateDisplay = installed;
@@ -34,7 +34,5 @@ export function expandShortcutText(): string {
34
34
  }
35
35
 
36
36
  export function showMoreHintText(): string {
37
- return isToolTuiFullscreen()
38
- ? "click to show more"
39
- : `${expandShortcutText()} to show more`;
37
+ return isToolTuiFullscreen() ? "click to show more" : `${expandShortcutText()} to show more`;
40
38
  }
@@ -128,8 +128,16 @@ export function summaryLine(data: AgentSummaryData): string {
128
128
  * `box` 为 true:markdown 引用块 `> *斜体内容*`(渲染为引用,主题 mdQuote=muted 即灰色,
129
129
  * 内容斜体)。entry renderer 场景直接用。
130
130
  * `box` 为 false:整体加粗单行。
131
+ * `colors`:成功/失败计数的 ANSI 前缀,取自主题(`theme.getFgAnsi("success")` /
132
+ * `theme.getFgAnsi("error")`),缺省不染色。仅数字染色:成功计数的数字染
133
+ * success 色、failed 计数的数字染 error 色,文本与时长不染色。颜色 span 以
134
+ * `\x1b[0m` 复位,引用块渲染器会在复位后重贴引用样式,后续文本不受影响。
131
135
  */
132
- export function summaryMarkdown(data: AgentSummaryData, box = false): string {
136
+ export function summaryMarkdown(
137
+ data: AgentSummaryData,
138
+ box = false,
139
+ colors: { success: string; failed: string } = { success: "", failed: "" },
140
+ ): string {
133
141
  const parts = summaryParts(data);
134
142
  if (parts.length === 0) return "";
135
143
  // 仅首段动词大写(与纯文本版“句首大写”一致)
@@ -137,7 +145,13 @@ export function summaryMarkdown(data: AgentSummaryData, box = false): string {
137
145
  const verb = part.match(/^[a-z]+/)?.[0] ?? "";
138
146
  return first && verb ? verb[0].toUpperCase() + verb.slice(1) + part.slice(verb.length) : part;
139
147
  };
140
- const text = parts.map((part, index) => capitalizeFirst(part, index === 0)).join(", ");
148
+ // 仅染数字:`Read 2 files` → `Read <色>2</色> files`
149
+ const paintNumber = (code: string, part: string) =>
150
+ code ? part.replace(/(\d+)/, `${code}$1\x1b[0m`) : part;
151
+ const text = parts
152
+ .map((part, index) => capitalizeFirst(part, index === 0))
153
+ .map((part) => paintNumber(part.endsWith("failed") ? colors.failed : colors.success, part))
154
+ .join(", ");
141
155
  const duration = formatDuration(data.durationMs);
142
156
  const line = duration ? `${text} · ${duration}` : text;
143
157
  return box ? `> *${line}*` : `**${line}**`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-cc-extensions",
3
- "version": "0.8.50",
3
+ "version": "0.8.51",
4
4
  "license": "MIT",
5
5
  "description": "A Pi productivity suite with Claude Code-style UI, context inspection, and agent/session references",
6
6
  "type": "module",
@@ -62,6 +62,7 @@
62
62
  },
63
63
  "devDependencies": {
64
64
  "@biomejs/biome": "2.5.5",
65
- "@types/node": "^26.1.1"
65
+ "@types/node": "^26.1.1",
66
+ "typescript": "^5.9.3"
66
67
  }
67
68
  }
@@ -24,7 +24,7 @@
24
24
  "selectedBg": "#252035",
25
25
  "userMessageBg": "#1e1e2e",
26
26
  "toolPendingBg": "#1b1924",
27
- "toolSuccessBg": "#18251f",
27
+ "toolSuccessBg": "#1e1e2e",
28
28
  "toolErrorBg": "#2a1b22",
29
29
  "customMessageBg": "#211c30"
30
30
  },
@@ -80,7 +80,7 @@
80
80
  "thinkingHigh": "accentBright",
81
81
  "thinkingXhigh": "#4db9cd",
82
82
  "thinkingMax": "cyan",
83
- "bashMode": "accent"
83
+ "bashMode": "green"
84
84
  },
85
85
  "export": {
86
86
  "pageBg": "bg",
@@ -81,7 +81,7 @@
81
81
  "thinkingHigh": "accentBright",
82
82
  "thinkingXhigh": "#4a8fa3",
83
83
  "thinkingMax": "cyan",
84
- "bashMode": "accent"
84
+ "bashMode": "green"
85
85
  },
86
86
  "export": {
87
87
  "pageBg": "bg",