@herbertgao/pi-extensions 2026.10.5 → 2026.10.6

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 (46) hide show
  1. package/README.md +2 -2
  2. package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +1 -2
  3. package/node_modules/@herbertgao/pi-cc-extensions/README.md +1 -2
  4. package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +5 -0
  5. package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +22 -0
  6. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/agent-summary/core.ts +2 -3
  7. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/compact-thinking.ts +1 -1
  8. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/context.ts +131 -28
  9. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/reference/index.ts +2 -0
  10. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/reference/subagent.ts +3 -0
  11. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/shell/footer.ts +10 -6
  12. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/shell/token-rate.ts +15 -3
  13. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/shell/working-message.ts +2 -23
  14. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +105 -55
  15. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/default-mode.ts +23 -471
  16. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/index.ts +6 -3
  17. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/markdown-enhance.ts +16 -83
  18. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/hover.ts +1 -1
  19. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/interaction.ts +2 -2
  20. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/packets.ts +1 -1
  21. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/sticky-prompt.ts +53 -5
  22. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/ask-user-question.ts +1 -1
  23. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/ccstyle-tool.ts +467 -0
  24. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/codemode.ts +1 -1
  25. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/ansi-utils.ts +1 -24
  26. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-edit-render.ts +1 -1
  27. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-limits.ts +1 -1
  28. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-text.ts +2 -1
  29. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-write-render.ts +1 -1
  30. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/line-width-safety.ts +1 -1
  31. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +53 -34
  32. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/message-display.ts +1 -1
  33. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/names.ts +41 -1
  34. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/result.ts +2 -862
  35. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/tool-io.ts +735 -0
  36. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/tool-state.ts +138 -0
  37. package/node_modules/@herbertgao/pi-cc-extensions/package.json +5 -4
  38. package/node_modules/@herbertgao/pi-cc-extensions/themes/cc-dark.json +1 -1
  39. package/node_modules/@herbertgao/pi-cc-extensions/themes/cc-light.json +2 -2
  40. package/node_modules/@herbertgao/pi-subagents/package.json +2 -1
  41. package/node_modules/@herbertgao/sol-pi/README.md +3 -3
  42. package/node_modules/@herbertgao/sol-pi/THIRD_PARTY_NOTICES.md +4 -4
  43. package/node_modules/@herbertgao/sol-pi/agents-install.md +3 -3
  44. package/node_modules/@herbertgao/sol-pi/docs/compatibility.md +1 -1
  45. package/package.json +2 -2
  46. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/show-more-hint.ts +0 -48
@@ -0,0 +1,138 @@
1
+ import { getToolMouseTui } from "../mouse/scroll.ts";
2
+ import { TOOL_LOADING_INTERVAL_MS, toolLoadingIcon } from "../../utils/tool-loading-icon.ts";
3
+
4
+ const activeAnimationContexts = new Set<any>();
5
+ let sharedAnimationTimer: ReturnType<typeof setTimeout> | null = null;
6
+
7
+ function clearAnimation(context: any) {
8
+ if (context?.state) context.state.ccstyleAnimationLight = false;
9
+ if (!context?.state?.ccstyleAnimationScheduled) return;
10
+ context.state.ccstyleAnimationScheduled = false;
11
+ activeAnimationContexts.delete(context);
12
+ if (activeAnimationContexts.size === 0 && sharedAnimationTimer) {
13
+ clearTimeout(sharedAnimationTimer);
14
+ sharedAnimationTimer = null;
15
+ }
16
+ }
17
+
18
+ export function clearAllAnimations() {
19
+ for (const ctx of activeAnimationContexts) {
20
+ ctx.state.ccstyleAnimationScheduled = false;
21
+ ctx.state.ccstyleAnimationLight = false;
22
+ }
23
+ activeAnimationContexts.clear();
24
+ if (sharedAnimationTimer) {
25
+ clearTimeout(sharedAnimationTimer);
26
+ sharedAnimationTimer = null;
27
+ }
28
+ }
29
+
30
+ export function scheduleAnimation(
31
+ context: any,
32
+ options: { light?: boolean; intervalMs?: number } = {},
33
+ ) {
34
+ const state = (context.state ??= {});
35
+ // light:调用方自己在 render() 内重取 loading 帧,定时器只需请求重绘;
36
+ // 否则定时器走 context.invalidate()(compact 摘要等靠它重建)。
37
+ // 每次调用都按本次 options 写入,避免上次 light 残留后非 light 调用仍跳过 invalidate。
38
+ state.ccstyleAnimationLight = Boolean(options.light);
39
+ if (state.ccstyleAnimationScheduled) return;
40
+ state.ccstyleAnimationScheduled = true;
41
+ activeAnimationContexts.add(context);
42
+ if (!sharedAnimationTimer) {
43
+ sharedAnimationTimer = setTimeout(() => {
44
+ sharedAnimationTimer = null;
45
+ const contexts = Array.from(activeAnimationContexts);
46
+ activeAnimationContexts.clear();
47
+ const tui = getToolMouseTui();
48
+ const canRequestRender = typeof tui?.requestRender === "function";
49
+ let lightFrames = false;
50
+ for (const ctx of contexts) {
51
+ ctx.state.ccstyleAnimationScheduled = false;
52
+ if (ctx.state.ccstyleAnimationLight && canRequestRender) lightFrames = true;
53
+ else ctx.invalidate?.();
54
+ }
55
+ if (lightFrames) tui.requestRender();
56
+ }, options.intervalMs ?? TOOL_LOADING_INTERVAL_MS);
57
+ }
58
+ }
59
+
60
+ /**
61
+ * 本回合流式消息里出现过的工具调用。Pi 要等整条 assistant 消息结束才派发执行,
62
+ * 这段窗口工具行已经在等启动,spinner 该逐帧转。
63
+ * 恢复或翻历史重建的旧行不在这个集合里,保持静止。
64
+ */
65
+ const liveToolCalls = new Set<string>();
66
+
67
+ /** 收下当前流式 assistant 消息里的工具调用 id。 */
68
+ export function noteStreamingToolCalls(message: any): void {
69
+ const content = Array.isArray(message?.content) ? message.content : [];
70
+ for (const block of content) {
71
+ const id = block?.type === "toolCall" ? block.id : undefined;
72
+ if (typeof id === "string" && id) liveToolCalls.add(id);
73
+ }
74
+ }
75
+
76
+ /** 工具收尾后移出等待窗口。 */
77
+ export function retireLiveToolCall(toolCallId: unknown): void {
78
+ if (typeof toolCallId === "string") liveToolCalls.delete(toolCallId);
79
+ }
80
+
81
+ export function clearLiveToolCalls(): void {
82
+ liveToolCalls.clear();
83
+ }
84
+
85
+ /** 工具行是否处于等待窗口(流式声明中或等待派发)。 */
86
+ export function isLiveToolCall(toolCallId: unknown): boolean {
87
+ return typeof toolCallId === "string" && liveToolCalls.has(toolCallId);
88
+ }
89
+
90
+ export function pendingIcon(_name: string): string {
91
+ return toolLoadingIcon();
92
+ }
93
+
94
+ type ToolVisualState = "pending" | "success" | "error";
95
+
96
+ export function settledIcon(name: string, state: ToolVisualState | undefined): string {
97
+ if (state === "success") return "✓";
98
+ if (state === "error") return "✗";
99
+ // toolIcon(name) 曾恒返回 "●",已内联;name 保留以稳定导出签名。
100
+ return "●";
101
+ }
102
+
103
+ export function setToolVisualState(context: any, visualState: ToolVisualState) {
104
+ const state = (context.state ??= {});
105
+ if (visualState !== "pending") clearAnimation(context);
106
+ if (state.ccstyleToolVisualState === visualState) return;
107
+ state.ccstyleToolVisualState = visualState;
108
+ // Do not invalidate synchronously from renderResult. Pi is already rendering
109
+ // this tool row; recursively scheduling another render here can retain both
110
+ // the finalized result component and its previous secondary/partial component,
111
+ // which displays the result summary twice. The current render pass also
112
+ // refreshes renderCall, so the settled icon still updates immediately.
113
+ }
114
+
115
+ function getToolVisualState(context: any): ToolVisualState | undefined {
116
+ return context?.state?.ccstyleToolVisualState as ToolVisualState | undefined;
117
+ }
118
+
119
+ export function resolveToolVisualState(context: any): ToolVisualState | undefined {
120
+ const visualState = getToolVisualState(context);
121
+ if (visualState || context?.isPartial !== false) return visualState;
122
+ const settledState: ToolVisualState = context?.isError ? "error" : "success";
123
+ setToolVisualState(context, settledState);
124
+ return settledState;
125
+ }
126
+
127
+ export function toolIconColor(context: any): "accent" | "error" | "success" | "muted" {
128
+ const visualState = getToolVisualState(context);
129
+ if (context?.isError || visualState === "error") return "error";
130
+ if (visualState === "success") return "success";
131
+ if (context?.isPartial || context?.executionStarted || visualState === "pending") return "accent";
132
+ return "muted";
133
+ }
134
+
135
+ export function isToolExpanded(options: any, context: any): boolean {
136
+ const local = context?.state?.ccstyleToolExpanded;
137
+ return typeof local === "boolean" ? local : Boolean(options?.expanded ?? context?.expanded);
138
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@herbertgao/pi-cc-extensions",
3
- "version": "0.12.0",
3
+ "version": "1.0.3-local.1",
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",
@@ -71,9 +71,10 @@
71
71
  },
72
72
  "x-upstream": {
73
73
  "package": "pi-cc-extensions",
74
- "version": "1.0.1",
75
- "reviewedVersion": "1.0.1",
74
+ "version": "1.0.3",
75
+ "reviewedVersion": "1.0.3",
76
76
  "repository": "https://github.com/minuque/pi-cc-extensions",
77
- "commit": "0188b76f2597772bea3b42075857e030d9a89666"
77
+ "commit": "281d23faa1567713ce43469b99e499ff7da31b74",
78
+ "trackVersion": true
78
79
  }
79
80
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "$schema": "https://raw.githubusercontent.com/earendil-works/pi/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
2
+ "$schema": "https://pi.dev/schemas/theme.schema.json",
3
3
  "name": "cc-dark",
4
4
  "vars": {
5
5
  "bg": "#131217",
@@ -1,5 +1,5 @@
1
1
  {
2
- "$schema": "https://raw.githubusercontent.com/earendil-works/pi/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
2
+ "$schema": "https://pi.dev/schemas/theme.schema.json",
3
3
  "name": "cc-light",
4
4
  "vars": {
5
5
  "bg": "#f7f7f8",
@@ -79,7 +79,7 @@
79
79
  "thinkingLow": "blue",
80
80
  "thinkingMedium": "accent",
81
81
  "thinkingHigh": "accentBright",
82
- "thinkingXhigh": "#4a8fa3",
82
+ "thinkingXhigh": "#0e7490",
83
83
  "thinkingMax": "cyan",
84
84
  "bashMode": "green"
85
85
  },
@@ -72,6 +72,7 @@
72
72
  "version": "0.20.0",
73
73
  "reviewedVersion": "0.20.0",
74
74
  "repository": "https://github.com/tintinweb/pi-subagents",
75
- "commit": "13106ab6f608b3acc54185da5299ee7fbaabb6b9"
75
+ "commit": "13106ab6f608b3acc54185da5299ee7fbaabb6b9",
76
+ "trackVersion": true
76
77
  }
77
78
  }
@@ -63,14 +63,14 @@ Read our paper: [SoL-Pi: Recursively Scaling Auto-Research Loops for Efficient A
63
63
 
64
64
  - Node.js 24 or newer
65
65
  - npm
66
- - `@earendil-works/pi-coding-agent` 1.0.4 (the monorepo's tested host; runtime peers remain `*`)
66
+ - `@earendil-works/pi-coding-agent` 1.2.0 (the monorepo's tested host; runtime peers remain `*`)
67
67
 
68
68
  ### Install
69
69
 
70
70
  Install the tested Pi release:
71
71
 
72
72
  ```bash
73
- npm install --global @earendil-works/pi-coding-agent@1.0.4
73
+ npm install --global @earendil-works/pi-coding-agent@1.2.0
74
74
  ```
75
75
 
76
76
  Install this independently maintained package, or use `@herbertgao/pi-extensions` for the collection:
@@ -149,7 +149,7 @@ bun audit
149
149
  node packages/sol-pi/scripts/check-pi-compat.mjs
150
150
  ```
151
151
 
152
- For package-only checks, run `bun run --cwd packages/sol-pi typecheck` and `bun run --cwd packages/sol-pi test`, then inspect the package with `npm pack --dry-run` from `packages/sol-pi`. Root development dependencies provide Pi 1.0.4; runtime Pi packages remain peer dependencies so Pi owns their installation and upgrades.
152
+ For package-only checks, run `bun run --cwd packages/sol-pi typecheck` and `bun run --cwd packages/sol-pi test`, then inspect the package with `npm pack --dry-run` from `packages/sol-pi`. Root development dependencies provide Pi 1.2.0; runtime Pi packages remain peer dependencies so Pi owns their installation and upgrades.
153
153
 
154
154
  ## Project Status
155
155
 
@@ -8,10 +8,10 @@ The following packages are supplied by the user's Pi installation and retain the
8
8
 
9
9
  | Package | Development-tested version | License | Source |
10
10
  | --- | ---: | --- | --- |
11
- | `@earendil-works/pi-agent-core` | 1.0.4 | MIT | <https://github.com/earendil-works/pi> |
12
- | `@earendil-works/pi-ai` | 1.0.4 | MIT | <https://github.com/earendil-works/pi> |
13
- | `@earendil-works/pi-coding-agent` | 1.0.4 | MIT | <https://github.com/earendil-works/pi> |
14
- | `@earendil-works/pi-tui` | 1.0.4 | MIT | <https://github.com/earendil-works/pi> |
11
+ | `@earendil-works/pi-agent-core` | 1.2.0 | MIT | <https://github.com/earendil-works/pi> |
12
+ | `@earendil-works/pi-ai` | 1.2.0 | MIT | <https://github.com/earendil-works/pi> |
13
+ | `@earendil-works/pi-coding-agent` | 1.2.0 | MIT | <https://github.com/earendil-works/pi> |
14
+ | `@earendil-works/pi-tui` | 1.2.0 | MIT | <https://github.com/earendil-works/pi> |
15
15
  | `typebox` | 1.3.7 | MIT | <https://github.com/sinclairzx81/typebox> |
16
16
 
17
17
  ## Development-only dependencies
@@ -7,7 +7,7 @@ Installation and configuration are complete only when Pi remains unmodified, the
7
7
  ## Rules
8
8
 
9
9
  - Do not modify, patch, fork, or vendor upstream Pi. SoL-Pi must load as a standalone extension through Pi's public package interface.
10
- - Use Node.js 24 or newer and the tested Pi release `@earendil-works/pi-coding-agent@1.0.4`. Treat a different Pi version as a compatibility change and rerun the full suite before using it.
10
+ - Use Node.js 24 or newer and the tested Pi release `@earendil-works/pi-coding-agent@1.2.0`. Treat a different Pi version as a compatibility change and rerun the full suite before using it.
11
11
  - Do not clean, reset, switch, or overwrite unrelated repository changes.
12
12
  - Do not print, log, commit, upload, or include any secret in a command line. Check only whether a credential is present.
13
13
  - Keep SoL-Pi settings in `sol-pi.json`. The Evidence-Preserving Reducer provider/model route is a SoL-Pi setting; provider URLs, credentials, the main agent model, and shell behavior remain Pi settings.
@@ -57,11 +57,11 @@ Stop if any command fails. Do not hide a failure with `|| true` or replace the f
57
57
  Install the tested Pi release without changing its source:
58
58
 
59
59
  ```bash
60
- npm install --global --ignore-scripts @earendil-works/pi-coding-agent@1.0.4
60
+ npm install --global --ignore-scripts @earendil-works/pi-coding-agent@1.2.0
61
61
  pi --version
62
62
  ```
63
63
 
64
- Require `pi --version` to report `1.0.4`. Runtime peer ranges remain `*`; other hosts need their own validation.
64
+ Require `pi --version` to report `1.2.0`. Runtime peer ranges remain `*`; other hosts need their own validation.
65
65
 
66
66
  For a project-local registration, run this from `target_project` and substitute the resolved absolute `sol_pi_root`:
67
67
 
@@ -1,6 +1,6 @@
1
1
  # Pi Compatibility
2
2
 
3
- This monorepo tests `@herbertgao/sol-pi` against the root development host Pi 1.0.4. Pi runtime peers remain `*`, so Pi owns installation and upgrades; that range is not a guarantee for every host. Upstream reports a 19-file/140-test suite and offline startup passing on 0.85.1 and 0.84.2, with earlier public-API checks on the 0.81.1 fork. Those are historical upstream results, not results for the locally adapted package. Its tests use Pi 1.x `ExtensionToolContext` for tool execution.
3
+ This monorepo tests `@herbertgao/sol-pi` against the root development host Pi 1.2.0. Pi runtime peers remain `*`, so Pi owns installation and upgrades; that range is not a guarantee for every host. Upstream reports a 19-file/140-test suite and offline startup passing on 0.85.1 and 0.84.2, with earlier public-API checks on the 0.81.1 fork. Those are historical upstream results, not results for the locally adapted package. Its tests use Pi 1.x `ExtensionToolContext` for tool execution.
4
4
 
5
5
  SoL-Pi imports only public package exports:
6
6
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@herbertgao/pi-extensions",
3
- "version": "2026.10.5",
3
+ "version": "2026.10.6",
4
4
  "description": "Aggregate installer for HerbertGao-maintained Pi extensions.",
5
5
  "keywords": [
6
6
  "extensions",
@@ -40,7 +40,7 @@
40
40
  "@dietrichgebert/ponytail": "5.1.0",
41
41
  "@herbertgao/pi-agency": "0.1.0",
42
42
  "@herbertgao/pi-bark": "0.2.0",
43
- "@herbertgao/pi-cc-extensions": "0.12.0",
43
+ "@herbertgao/pi-cc-extensions": "1.0.3-local.1",
44
44
  "@herbertgao/pi-subagents": "0.19.0",
45
45
  "@herbertgao/sol-pi": "0.4.0",
46
46
  "@juicesharp/rpiv-ask-user-question": "2.12.0",
@@ -1,48 +0,0 @@
1
- /**
2
- * show-more 提示文本:fullscreen 下鼠标 hover/click 可用,提示 "click to show more";
3
- * 其他模式(regular 保留终端原生 scrollback、不启用鼠标上报)提示默认展开快捷键。
4
- *
5
- * tui 模式由 mouse-interaction 在 renderer 回调中维护;未安装时按 fullscreen 处理,
6
- * 保证纯渲染测试与既有行为不变。
7
- */
8
- import { getKeybindings } from "@earendil-works/pi-tui";
9
-
10
- let toolTuiFullscreen: boolean | undefined;
11
-
12
- export function setToolTuiFullscreen(value: boolean): void {
13
- toolTuiFullscreen = value;
14
- }
15
-
16
- export function isToolTuiFullscreen(): boolean {
17
- return toolTuiFullscreen !== false;
18
- }
19
-
20
- function formatKeyPart(part: string): string {
21
- // 与 pi 内置 keybinding-hints 一致:macOS 上 alt 显示为 option
22
- return process.platform === "darwin" && part.toLowerCase() === "alt" ? "option" : part;
23
- }
24
-
25
- /** 默认展开快捷键(app.tools.expand)显示文本;未配置时回退 ctrl+o。 */
26
- export function expandShortcutText(): string {
27
- const keys = getKeybindings().getKeys("app.tools.expand");
28
- if (keys.length === 0) return "ctrl+o";
29
- return keys
30
- .join("/")
31
- .split("/")
32
- .map((part) => part.split("+").map(formatKeyPart).join("+"))
33
- .join("/");
34
- }
35
-
36
- export function showMoreHintText(): string {
37
- return isToolTuiFullscreen() ? "click to show more" : `${expandShortcutText()} to show more`;
38
- }
39
-
40
- /** 展开卡的收起提示,与折叠态 showMoreHintText 同一位置对称。 */
41
- export function collapseHintText(): string {
42
- return isToolTuiFullscreen() ? "↑ Collapse" : `${expandShortcutText()} to collapse`;
43
- }
44
-
45
- /** 该行是否带展开态收起提示(用于展开卡的 hint hover 命中)。 */
46
- export function isCollapseHintLine(plainLine: string): boolean {
47
- return plainLine.includes(collapseHintText());
48
- }