pi-cc-extensions 0.8.37 → 0.8.40
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/README.en.md +3 -31
- package/README.md +13 -43
- package/extensions/claude-code-style.ts +6 -1
- package/extensions/fixed-editor.ts +29 -14
- package/extensions/working-message.ts +12 -12
- package/package.json +1 -1
- package/themes/github-dark-default.json +1 -1
- package/assets/readme/context-preview.webp +0 -0
- package/assets/readme/context-usage.webp +0 -0
- package/assets/readme/fixed-editor-navigation.webp +0 -0
- package/assets/readme/session-reference.webp +0 -0
package/README.en.md
CHANGED
|
@@ -22,39 +22,11 @@
|
|
|
22
22
|
## Preview
|
|
23
23
|
|
|
24
24
|
<table>
|
|
25
|
-
<
|
|
26
|
-
<td colspan="2" align="center">
|
|
27
|
-
<img src="./assets/readme/welcome.webp" width="100%" alt="Pi welcome screen">
|
|
28
|
-
<br>
|
|
29
|
-
<sub><b>Welcome screen</b><br><code>npm:pi-startup-header</code> with <code>npm:pi-zentui</code></sub>
|
|
30
|
-
</td>
|
|
31
|
-
</tr>
|
|
32
|
-
<tr>
|
|
33
|
-
<td width="50%" align="center">
|
|
34
|
-
<img src="./assets/readme/fixed-editor-navigation.webp" width="100%" alt="Tool results, back-to-bottom control, and Ctrl+End in the fixed editor">
|
|
35
|
-
<br>
|
|
36
|
-
<sub><b>Fixed-editor workflow</b><br>Tool summaries, expand/collapse, and keyboard navigation</sub>
|
|
37
|
-
</td>
|
|
38
|
-
<td width="50%" align="center">
|
|
39
|
-
<img src="./assets/readme/session-reference.webp" width="100%" alt="Selecting a previous Session through at-sign completion">
|
|
40
|
-
<br>
|
|
41
|
-
<sub><b>Session references</b><br>Find and inject previous context through completion</sub>
|
|
42
|
-
</td>
|
|
43
|
-
</tr>
|
|
44
|
-
<tr>
|
|
45
|
-
<td width="50%" align="center">
|
|
46
|
-
<img src="./assets/readme/context-usage.webp" width="100%" alt="Context window usage breakdown">
|
|
47
|
-
<br>
|
|
48
|
-
<sub><b>Context usage</b><br>Inspect usage by category</sub>
|
|
49
|
-
</td>
|
|
50
|
-
<td width="50%" align="center">
|
|
51
|
-
<img src="./assets/readme/context-preview.webp" width="100%" alt="Previewing injected context">
|
|
52
|
-
<br>
|
|
53
|
-
<sub><b>Context preview</b><br>Inspect the content injected into the model</sub>
|
|
54
|
-
</td>
|
|
55
|
-
</tr>
|
|
25
|
+
<img src="./assets/readme/welcome.webp" width="100%" alt="Pi welcome screen">
|
|
56
26
|
</table>
|
|
57
27
|
|
|
28
|
+
https://github.com/user-attachments/assets/4ae094d2-7480-484b-a0c8-6e782495ce9f
|
|
29
|
+
|
|
58
30
|
## Quick start
|
|
59
31
|
|
|
60
32
|
```bash
|
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
</p>
|
|
11
11
|
|
|
12
12
|
<p align="center">
|
|
13
|
-
Claude Code 风格界面、固定编辑器、上下文检查,以及 Agent / Session 引用。
|
|
13
|
+
类 Claude Code 风格界面、固定编辑器、上下文检查,以及 Agent / Session 引用。
|
|
14
14
|
</p>
|
|
15
15
|
|
|
16
16
|
<p align="center">
|
|
@@ -22,39 +22,11 @@
|
|
|
22
22
|
## 界面预览
|
|
23
23
|
|
|
24
24
|
<table>
|
|
25
|
-
|
|
26
|
-
<td colspan="2" align="center">
|
|
27
|
-
<img src="./assets/readme/welcome.webp" width="100%" alt="Pi 启动后的欢迎界面">
|
|
28
|
-
<br>
|
|
29
|
-
<sub><b>欢迎界面</b><br> @ <code>npm:pi-startup-header</code> 与 <code>npm:pi-zentui</code></sub>
|
|
30
|
-
</td>
|
|
31
|
-
</tr>
|
|
32
|
-
<tr>
|
|
33
|
-
<td width="50%" align="center">
|
|
34
|
-
<img src="./assets/readme/fixed-editor-navigation.webp" width="100%" alt="Pi fixed-editor 中的工具结果、回到底部按钮与 Ctrl+End 快捷键">
|
|
35
|
-
<br>
|
|
36
|
-
<sub><b>固定编辑器工作流</b><br>工具结果摘要、折叠展开与键盘导航</sub>
|
|
37
|
-
</td>
|
|
38
|
-
<td width="50%" align="center">
|
|
39
|
-
<img src="./assets/readme/session-reference.webp" width="100%" alt="在 Pi 中通过 @ 补全选择历史 Session">
|
|
40
|
-
<br>
|
|
41
|
-
<sub><b>历史 Session 引用</b><br>通过 @ 补全快速找到并引用历史会话</sub>
|
|
42
|
-
</td>
|
|
43
|
-
</tr>
|
|
44
|
-
<tr>
|
|
45
|
-
<td width="50%" align="center">
|
|
46
|
-
<img src="./assets/readme/context-usage.webp" width="100%" alt="Pi 上下文窗口用量查看器">
|
|
47
|
-
<br>
|
|
48
|
-
<sub><b>上下文用量</b><br>查看 System prompt、Tools、Skills 等占用分布</sub>
|
|
49
|
-
</td>
|
|
50
|
-
<td width="50%" align="center">
|
|
51
|
-
<img src="./assets/readme/context-preview.webp" width="100%" alt="Pi 中展开查看 System Prompt 内容">
|
|
52
|
-
<br>
|
|
53
|
-
<sub><b>上下文预览</b><br>按类别展开查看实际注入的上下文内容</sub>
|
|
54
|
-
</td>
|
|
55
|
-
</tr>
|
|
25
|
+
<img src="./assets/readme/welcome.webp" width="100%" alt="Pi 启动后的欢迎界面">
|
|
56
26
|
</table>
|
|
57
27
|
|
|
28
|
+
https://github.com/user-attachments/assets/4ae094d2-7480-484b-a0c8-6e782495ce9f
|
|
29
|
+
|
|
58
30
|
## 快速开始
|
|
59
31
|
|
|
60
32
|
```bash
|
|
@@ -68,14 +40,13 @@ pi install git:github.com/minuque/pi-cc-extensions
|
|
|
68
40
|
|
|
69
41
|
## 功能
|
|
70
42
|
|
|
71
|
-
|
|
72
|
-
|
|
|
73
|
-
|
|
|
74
|
-
|
|
|
75
|
-
|
|
|
76
|
-
|
|
|
77
|
-
|
|
|
78
|
-
| 主题 | 随包提供内置 GitHub Dark Default 主题 | `/theme` |
|
|
43
|
+
| 功能 | 说明 | 入口 |
|
|
44
|
+
| -------------------- | ------------------------------------------------------------------------------------- | ------------- |
|
|
45
|
+
| Claude Code 风格输出 | 工具摘要、折叠展开、rich edit/write diff,以及`on` / `off` / `compact` 三种模式 | `/ccstyle` |
|
|
46
|
+
| Fixed editor 交互 | 基于`@tifan/pi-fixed-editor`,支持动态开关、每刻度 5 行滚动、工具点击与回到底部 | `/ccstyle` |
|
|
47
|
+
| 上下文检查 | 查看上下文占用,并预览 System prompt、Tools、Skills 和消息内容 | `/context` |
|
|
48
|
+
| Session 引用 | 搜索并注入历史 Session 或现有 SubAgent 的有效上下文 | `@session:` |
|
|
49
|
+
| 主题 | 随包提供内置 GitHub Dark Default 主题 | `/theme` |
|
|
79
50
|
|
|
80
51
|
## 本地开发
|
|
81
52
|
|
|
@@ -95,9 +66,8 @@ pi -e .
|
|
|
95
66
|
|
|
96
67
|
## 推荐搭配
|
|
97
68
|
|
|
98
|
-
|
|
99
|
-
|
|
|
100
|
-
| ------------------------------- | ------------------------------------- |
|
|
69
|
+
| 扩展 | 用途 |
|
|
70
|
+
| ------------------------------- | ----------------------------------- |
|
|
101
71
|
| `npm:@tintinweb/pi-subagents` | 并行 SubAgent、后台任务与工作树隔离 |
|
|
102
72
|
| `npm:pi-mcp-adapter` | 按需发现 MCP 工具,减少上下文占用 |
|
|
103
73
|
| `npm:pi-theme-picker` | 主题搜索和实时预览 |
|
|
@@ -3171,7 +3171,12 @@ export default function (
|
|
|
3171
3171
|
const tui = toolMouseTui;
|
|
3172
3172
|
if (!tui) return;
|
|
3173
3173
|
if (toolMouseFixedFeaturesEnabled) patchToolMouseInputCapture(tui);
|
|
3174
|
-
|
|
3174
|
+
// compositor.install captured the current chain as originalDoRender, so an
|
|
3175
|
+
// already-installed wrapper keeps receiving calls through it — re-wrapping
|
|
3176
|
+
// only when no wrapper is active avoids stacking one per rebuild/reload.
|
|
3177
|
+
if (!(toolMouseRenderPatchTui === tui && toolMouseRenderPatchState?.active)) {
|
|
3178
|
+
patchToolMouseMotionAfterRender(tui);
|
|
3179
|
+
}
|
|
3175
3180
|
tui.requestRender?.(true);
|
|
3176
3181
|
});
|
|
3177
3182
|
const writeExecutionMetadata = installWriteOverride(pi, new WriteExecutionMetadataStore());
|
|
@@ -170,7 +170,10 @@ export function installFixedEditorImePatch(compositorClass: {
|
|
|
170
170
|
const wasInstalled = Boolean(this.installed);
|
|
171
171
|
const result = Reflect.apply(originalInstall, this, args);
|
|
172
172
|
// Dependents re-wrap doRender only after the compositor actually owns it.
|
|
173
|
-
|
|
173
|
+
// Read the global each time: the patch survives /reload on the shared
|
|
174
|
+
// prototype while the owner callback belongs to the live extension module.
|
|
175
|
+
if (!wasInstalled && this.installed && !this.disposed)
|
|
176
|
+
getCompositorInstallNotify()?.callback();
|
|
174
177
|
return result;
|
|
175
178
|
};
|
|
176
179
|
prototype[MOUSE_WRITE_PATCH] = true;
|
|
@@ -211,9 +214,22 @@ type FixedEditorOwner = {
|
|
|
211
214
|
const FIXED_EDITOR_OWNER = Symbol.for("pi.ccstyle.fixed-editor-owner");
|
|
212
215
|
const FIXED_EDITOR_FOOTER_HOOK = Symbol.for("pi.ccstyle.fixed-editor-footer-hook");
|
|
213
216
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
+
// /reload keeps the same TerminalSplitCompositor.prototype, so the install hook
|
|
218
|
+
// patched by the pre-reload module must read a cross-reload global instead of a
|
|
219
|
+
// module-local variable; otherwise notifyRebuild never fires after reload and
|
|
220
|
+
// dependents (ccstyle mouse input capture) stay unbound.
|
|
221
|
+
const COMPOSITOR_INSTALL_NOTIFY_KEY = Symbol.for("pi.ccstyle.compositor-install-notify");
|
|
222
|
+
|
|
223
|
+
type CompositorInstallNotify = { owner: object; callback: () => void };
|
|
224
|
+
function getCompositorInstallNotify(): CompositorInstallNotify | undefined {
|
|
225
|
+
return (globalThis as Record<PropertyKey, unknown>)[COMPOSITOR_INSTALL_NOTIFY_KEY] as
|
|
226
|
+
| CompositorInstallNotify
|
|
227
|
+
| undefined;
|
|
228
|
+
}
|
|
229
|
+
function setCompositorInstallNotify(value: CompositorInstallNotify | undefined): void {
|
|
230
|
+
if (value) (globalThis as Record<PropertyKey, unknown>)[COMPOSITOR_INSTALL_NOTIFY_KEY] = value;
|
|
231
|
+
else delete (globalThis as Record<PropertyKey, unknown>)[COMPOSITOR_INSTALL_NOTIFY_KEY];
|
|
232
|
+
}
|
|
217
233
|
/** Runs before fixed-editor start/probe so dependents can unwrap doRender before capture. */
|
|
218
234
|
let beforeFixedEditorStart: (() => void) | undefined;
|
|
219
235
|
|
|
@@ -289,10 +305,7 @@ export function installFixedEditor(
|
|
|
289
305
|
});
|
|
290
306
|
};
|
|
291
307
|
function clearInstallNotify() {
|
|
292
|
-
if (
|
|
293
|
-
compositorInstallNotify = undefined;
|
|
294
|
-
compositorInstallNotifyOwner = undefined;
|
|
295
|
-
}
|
|
308
|
+
if (getCompositorInstallNotify()?.owner === owner) setCompositorInstallNotify(undefined);
|
|
296
309
|
}
|
|
297
310
|
function deactivate() {
|
|
298
311
|
fixedEditorState.scrollButtonHitbox = null;
|
|
@@ -311,12 +324,14 @@ export function installFixedEditor(
|
|
|
311
324
|
if (previous?.owner !== owner) previous?.stop();
|
|
312
325
|
const currentSession = session;
|
|
313
326
|
// Register before start/probe so the first real compositor.install notifies us.
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
327
|
+
setCompositorInstallNotify({
|
|
328
|
+
owner,
|
|
329
|
+
callback: () => {
|
|
330
|
+
if (!active) return;
|
|
331
|
+
if ((globalThis as any)[FIXED_EDITOR_OWNER]?.owner !== owner) return;
|
|
332
|
+
notifyRebuild();
|
|
333
|
+
},
|
|
334
|
+
});
|
|
320
335
|
// Unwrap outer doRender patches before compositor construction captures it.
|
|
321
336
|
beforeFixedEditorStart?.();
|
|
322
337
|
start?.(currentSession.event, currentSession.ctx);
|
|
@@ -20,11 +20,12 @@ function formatCount(value: number): string {
|
|
|
20
20
|
|
|
21
21
|
function estimateTextLength(message: any): number {
|
|
22
22
|
if (!Array.isArray(message?.content)) return 0;
|
|
23
|
-
return message.content.reduce(
|
|
24
|
-
(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
return message.content.reduce((sum: number, block: any) => {
|
|
24
|
+
if (block?.type === "text" && typeof block.text === "string") return sum + block.text.length;
|
|
25
|
+
if (block?.type === "thinking" && block.thinkingSignature?.body)
|
|
26
|
+
return sum + (block.thinkingSignature.body as string).length;
|
|
27
|
+
return sum;
|
|
28
|
+
}, 0);
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
function textBlockLengths(message: any): number[] {
|
|
@@ -34,6 +35,8 @@ function textBlockLengths(message: any): number[] {
|
|
|
34
35
|
const block = message.content[index];
|
|
35
36
|
if (block?.type === "text" && typeof block.text === "string") {
|
|
36
37
|
lengths[index] = block.text.length;
|
|
38
|
+
} else if (block?.type === "thinking" && block.thinkingSignature?.body) {
|
|
39
|
+
lengths[index] = (block.thinkingSignature.body as string).length;
|
|
37
40
|
}
|
|
38
41
|
}
|
|
39
42
|
return lengths;
|
|
@@ -166,15 +169,12 @@ export default function (pi: ExtensionAPI): void {
|
|
|
166
169
|
|
|
167
170
|
if (evt.type === "start") {
|
|
168
171
|
resetResponseTracking(evt.partial);
|
|
169
|
-
} else if (evt.type === "text_start") {
|
|
172
|
+
} else if (evt.type === "thinking_start" || evt.type === "text_start") {
|
|
170
173
|
setTextBlockLength(evt.contentIndex, 0);
|
|
171
174
|
updateProviderUsage(evt.partial);
|
|
172
|
-
} else if (evt.type === "text_delta") {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
(responseTextBlockLengths[evt.contentIndex] ?? 0) +
|
|
176
|
-
(typeof evt.delta === "string" ? evt.delta.length : 0),
|
|
177
|
-
);
|
|
175
|
+
} else if (evt.type === "thinking_delta" || evt.type === "text_delta") {
|
|
176
|
+
const add = typeof evt.delta === "string" ? evt.delta.length : 0;
|
|
177
|
+
setTextBlockLength(evt.contentIndex, (responseTextBlockLengths[evt.contentIndex] ?? 0) + add);
|
|
178
178
|
updateProviderUsage(evt.partial);
|
|
179
179
|
} else if (evt.type === "text_end") {
|
|
180
180
|
setTextBlockLength(
|
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|