pi-cc-extensions 0.8.53 → 0.8.55
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 +12 -17
- package/README.md +18 -17
- package/assets/readme/hero.en.svg +101 -0
- package/extensions/config/config.ts +25 -17
- package/extensions/config/panel.ts +100 -4
- package/extensions/{utils/agent-summary.ts → feature/agent-summary/core.ts} +39 -47
- package/extensions/feature/{agent-summary.ts → agent-summary/index.ts} +2 -6
- package/extensions/feature/compact-thinking.ts +8 -3
- package/extensions/feature/{session-reference.ts → reference/index.ts} +1 -1
- package/extensions/feature/{agent-autocomplete.ts → reference/subagent.ts} +0 -1
- package/extensions/feature/{pi-startup-header.ts → shell/startup-header.ts} +2 -42
- package/extensions/feature/{working-message.ts → shell/working-message.ts} +5 -11
- package/extensions/index.ts +28 -38
- package/extensions/renderer/compact-mode.ts +394 -101
- package/extensions/renderer/default-mode.ts +747 -0
- package/extensions/renderer/index.ts +58 -775
- package/extensions/renderer/{mouse-hover.ts → mouse/hover.ts} +8 -6
- package/extensions/renderer/{mouse-interaction.ts → mouse/interaction.ts} +37 -36
- package/extensions/renderer/{mouse-layout.ts → mouse/layout.ts} +5 -21
- package/extensions/renderer/{mouse-packets.ts → mouse/packets.ts} +1 -1
- package/extensions/renderer/{mouse-scroll.ts → mouse/scroll.ts} +49 -36
- package/extensions/renderer/{tool-diff → tool/diff}/diff-renderer.ts +10 -45
- package/extensions/renderer/{tool-diff → tool/diff}/line-width-safety.ts +1 -1
- package/extensions/renderer/tool/diff/write-display-utils.ts +12 -0
- package/extensions/renderer/{tool-grouping.ts → tool/grouping.ts} +20 -16
- package/extensions/renderer/{tool-result.ts → tool/result.ts} +35 -27
- package/extensions/utils/ansi-color.ts +44 -0
- package/extensions/utils/format.ts +21 -0
- package/extensions/utils/fullscreen-detect.ts +0 -27
- package/package.json +4 -2
- package/extensions/renderer/tool-diff/write-display-utils.ts +0 -29
- /package/extensions/feature/{session-reference-core.ts → reference/session.ts} +0 -0
- /package/extensions/feature/{pi-aliases.ts → shell/aliases.ts} +0 -0
- /package/extensions/{feature → renderer}/markdown-enhance.ts +0 -0
- /package/extensions/renderer/{tool-diff → tool/diff}/ATTRIBUTION.md +0 -0
- /package/extensions/renderer/{tool-diff → tool/diff}/ansi-utils.ts +0 -0
- /package/extensions/renderer/{tool-diff → tool/diff}/diff-presentation.ts +0 -0
- /package/extensions/renderer/{tool-diff → tool/diff}/index.ts +0 -0
- /package/extensions/renderer/{tool-diff → tool/diff}/render-utils.ts +0 -0
- /package/extensions/renderer/{tool-diff → tool/diff}/shiki-highlight.ts +0 -0
- /package/extensions/renderer/{tool-diff → tool/diff}/types.ts +0 -0
- /package/extensions/renderer/{tool-diff → tool/diff}/write-execution.ts +0 -0
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Agent 回合摘要:统计一次 agent 运行的工具使用并格式化成摘要文本。
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* (MCP 风格 `server__read` 归入 other)。
|
|
4
|
+
* 分类:bash / read / edit / write / other(精确工具名;MCP 风格名归 other)。
|
|
5
|
+
* 计数:bash 按调用次数;read/edit/write 按非空 path/file_path 去重;other 按调用次数。
|
|
6
|
+
* 失败单独累计;另记回合耗时。
|
|
8
7
|
*
|
|
9
|
-
* 呈现:`summaryLine`
|
|
10
|
-
* 增强版——加粗统计词,box 模式包 `> [!TIP]` 提示框(由 markdown-enhance 渲染
|
|
11
|
-
* 成带图标的表格框),供当前 Markdown 渲染管线使用。
|
|
8
|
+
* 呈现:`summaryLine` 纯文本,`summaryMarkdown` Markdown(可 box 引用块)。
|
|
12
9
|
*/
|
|
13
10
|
|
|
14
11
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
12
|
+
import { formatDuration } from "../../utils/format.ts";
|
|
13
|
+
export { formatDuration };
|
|
15
14
|
|
|
16
|
-
/**
|
|
17
|
-
export type AgentToolCategory = "read" | "edit" | "
|
|
15
|
+
/** 工具分类。 */
|
|
16
|
+
export type AgentToolCategory = "bash" | "read" | "edit" | "write" | "other";
|
|
18
17
|
|
|
19
18
|
/** 一次 agent 回合的统计快照。 */
|
|
20
19
|
export type AgentSummaryData = {
|
|
20
|
+
commands: number;
|
|
21
21
|
reads: number;
|
|
22
22
|
edits: number;
|
|
23
|
-
|
|
23
|
+
writes: number;
|
|
24
24
|
others: number;
|
|
25
25
|
failed: number;
|
|
26
26
|
durationMs: number;
|
|
@@ -28,9 +28,10 @@ export type AgentSummaryData = {
|
|
|
28
28
|
|
|
29
29
|
export function classifyTool(toolName: string): AgentToolCategory {
|
|
30
30
|
const base = toolName.split(".").pop() ?? toolName;
|
|
31
|
-
if (base === "read") return "read";
|
|
32
|
-
if (base === "edit" || base === "write") return "edit";
|
|
33
31
|
if (base === "bash") return "bash";
|
|
32
|
+
if (base === "read") return "read";
|
|
33
|
+
if (base === "edit") return "edit";
|
|
34
|
+
if (base === "write") return "write";
|
|
34
35
|
return "other";
|
|
35
36
|
}
|
|
36
37
|
|
|
@@ -38,12 +39,18 @@ function nonEmptyString(value: unknown): value is string {
|
|
|
38
39
|
return typeof value === "string" && value.length > 0;
|
|
39
40
|
}
|
|
40
41
|
|
|
42
|
+
function toolPath(args?: Record<string, unknown> | null): string | undefined {
|
|
43
|
+
const path = args?.path ?? args?.file_path;
|
|
44
|
+
return nonEmptyString(path) ? path : undefined;
|
|
45
|
+
}
|
|
46
|
+
|
|
41
47
|
/** 累积一次 agent 回合的工具统计;agent_start 时新建实例。 */
|
|
42
48
|
export class AgentRunSummary {
|
|
43
49
|
toolCount = 0;
|
|
50
|
+
commandCount = 0;
|
|
44
51
|
readFiles = new Set<string>();
|
|
45
52
|
editFiles = new Set<string>();
|
|
46
|
-
|
|
53
|
+
writeFiles = new Set<string>();
|
|
47
54
|
otherCount = 0;
|
|
48
55
|
failedCount = 0;
|
|
49
56
|
|
|
@@ -56,16 +63,19 @@ export class AgentRunSummary {
|
|
|
56
63
|
/** tool_execution_start 时调用。 */
|
|
57
64
|
recordToolStart(toolName: string, args?: Record<string, unknown> | null): void {
|
|
58
65
|
this.toolCount++;
|
|
59
|
-
const path = args
|
|
66
|
+
const path = toolPath(args);
|
|
60
67
|
switch (classifyTool(toolName)) {
|
|
68
|
+
case "bash":
|
|
69
|
+
this.commandCount++;
|
|
70
|
+
break;
|
|
61
71
|
case "read":
|
|
62
|
-
if (
|
|
72
|
+
if (path) this.readFiles.add(path);
|
|
63
73
|
break;
|
|
64
74
|
case "edit":
|
|
65
|
-
if (
|
|
75
|
+
if (path) this.editFiles.add(path);
|
|
66
76
|
break;
|
|
67
|
-
case "
|
|
68
|
-
this.
|
|
77
|
+
case "write":
|
|
78
|
+
if (path) this.writeFiles.add(path);
|
|
69
79
|
break;
|
|
70
80
|
default:
|
|
71
81
|
this.otherCount++;
|
|
@@ -79,9 +89,10 @@ export class AgentRunSummary {
|
|
|
79
89
|
|
|
80
90
|
snapshot(now = Date.now()): AgentSummaryData {
|
|
81
91
|
return {
|
|
92
|
+
commands: this.commandCount,
|
|
82
93
|
reads: this.readFiles.size,
|
|
83
94
|
edits: this.editFiles.size,
|
|
84
|
-
|
|
95
|
+
writes: this.writeFiles.size,
|
|
85
96
|
others: this.otherCount,
|
|
86
97
|
failed: this.failedCount,
|
|
87
98
|
durationMs: now - this.startedAt,
|
|
@@ -89,31 +100,21 @@ export class AgentRunSummary {
|
|
|
89
100
|
}
|
|
90
101
|
}
|
|
91
102
|
|
|
92
|
-
/** 毫秒 → "1h 2m 3s"/"2m 3s"/"3s";低于 1 秒返回 ""(省略)。 */
|
|
93
|
-
export function formatDuration(ms: number): string {
|
|
94
|
-
const totalSec = Math.floor(ms / 1000);
|
|
95
|
-
if (totalSec < 1) return "";
|
|
96
|
-
const hours = Math.floor(totalSec / 3600);
|
|
97
|
-
const minutes = Math.floor((totalSec % 3600) / 60);
|
|
98
|
-
const seconds = totalSec % 60;
|
|
99
|
-
if (hours > 0) return `${hours}h ${minutes}m ${seconds}s`;
|
|
100
|
-
if (minutes > 0) return `${minutes}m ${seconds}s`;
|
|
101
|
-
return `${seconds}s`;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
103
|
const plural = (count: number) => (count === 1 ? "" : "s");
|
|
105
104
|
|
|
105
|
+
/** 输出顺序:bash → read → edit → write → other → failed。 */
|
|
106
106
|
function summaryParts(data: AgentSummaryData): string[] {
|
|
107
107
|
const parts: string[] = [];
|
|
108
|
+
if (data.commands) parts.push(`ran ${data.commands} command${plural(data.commands)}`);
|
|
108
109
|
if (data.reads) parts.push(`read ${data.reads} file${plural(data.reads)}`);
|
|
109
110
|
if (data.edits) parts.push(`edited ${data.edits} file${plural(data.edits)}`);
|
|
111
|
+
if (data.writes) parts.push(`wrote ${data.writes} file${plural(data.writes)}`);
|
|
110
112
|
if (data.others) parts.push(`${data.others} other tool${plural(data.others)}`);
|
|
111
|
-
if (data.commands) parts.push(`ran ${data.commands} command${plural(data.commands)}`);
|
|
112
113
|
if (data.failed) parts.push(`${data.failed} failed`);
|
|
113
114
|
return parts;
|
|
114
115
|
}
|
|
115
116
|
|
|
116
|
-
/**
|
|
117
|
+
/** 纯文本摘要行:句首大写 + 可选耗时。 */
|
|
117
118
|
export function summaryLine(data: AgentSummaryData): string {
|
|
118
119
|
const parts = summaryParts(data);
|
|
119
120
|
if (parts.length === 0) return "";
|
|
@@ -125,13 +126,8 @@ export function summaryLine(data: AgentSummaryData): string {
|
|
|
125
126
|
|
|
126
127
|
/**
|
|
127
128
|
* Markdown 摘要行。
|
|
128
|
-
* `box` 为 true
|
|
129
|
-
*
|
|
130
|
-
* `box` 为 false:整体加粗单行。
|
|
131
|
-
* `colors`:成功/失败计数的 ANSI 前缀,取自主题(`theme.getFgAnsi("success")` /
|
|
132
|
-
* `theme.getFgAnsi("error")`),缺省不染色。仅数字染色:成功计数的数字染
|
|
133
|
-
* success 色、failed 计数的数字染 error 色,文本与时长不染色。颜色 span 以
|
|
134
|
-
* `\x1b[0m` 复位,引用块渲染器会在复位后重贴引用样式,后续文本不受影响。
|
|
129
|
+
* `box` 为 true:引用块 `> *斜体*`;false:整体加粗。
|
|
130
|
+
* `colors`:仅数字染色(success / failed)。
|
|
135
131
|
*/
|
|
136
132
|
export function summaryMarkdown(
|
|
137
133
|
data: AgentSummaryData,
|
|
@@ -140,12 +136,10 @@ export function summaryMarkdown(
|
|
|
140
136
|
): string {
|
|
141
137
|
const parts = summaryParts(data);
|
|
142
138
|
if (parts.length === 0) return "";
|
|
143
|
-
// 仅首段动词大写(与纯文本版“句首大写”一致)
|
|
144
139
|
const capitalizeFirst = (part: string, first: boolean) => {
|
|
145
140
|
const verb = part.match(/^[a-z]+/)?.[0] ?? "";
|
|
146
141
|
return first && verb ? verb[0].toUpperCase() + verb.slice(1) + part.slice(verb.length) : part;
|
|
147
142
|
};
|
|
148
|
-
// 仅染数字:`Read 2 files` → `Read <色>2</色> files`
|
|
149
143
|
const paintNumber = (code: string, part: string) =>
|
|
150
144
|
code ? part.replace(/(\d+)/, `${code}$1\x1b[0m`) : part;
|
|
151
145
|
const text = parts
|
|
@@ -159,11 +153,9 @@ export function summaryMarkdown(
|
|
|
159
153
|
|
|
160
154
|
/**
|
|
161
155
|
* 绑定 pi 事件到摘要统计:
|
|
162
|
-
* - agent_start
|
|
163
|
-
* - tool_execution_start /
|
|
164
|
-
* - agent_end
|
|
165
|
-
*
|
|
166
|
-
* 返回取消函数:清除当前统计引用(pi.on 不支持解绑,取消后不再产生回调)。
|
|
156
|
+
* - agent_start 重置
|
|
157
|
+
* - tool_execution_start / end 累计
|
|
158
|
+
* - agent_end 回调(toolCount < minToolCount 跳过)
|
|
167
159
|
*/
|
|
168
160
|
export function bindAgentSummary(
|
|
169
161
|
pi: ExtensionAPI,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Agent 回合摘要展示:agent_end 时把本回合工具统计写入会话条目,
|
|
3
3
|
* 由 entry renderer 渲染为 markdown 引用块 `> [!TIP] *斜体内容*`。
|
|
4
4
|
*
|
|
5
|
-
* 统计复用
|
|
5
|
+
* 统计复用 ./core.ts(bash/read/edit/write/other)。
|
|
6
6
|
* appendEntry 不进 LLM 上下文,只显示在聊天区。
|
|
7
7
|
* 引用块文字色取主题 mdQuote(cc 主题下为 muted 灰),内容用 *斜体* 语法。
|
|
8
8
|
*/
|
|
@@ -10,11 +10,7 @@
|
|
|
10
10
|
import { Markdown } from "@earendil-works/pi-tui";
|
|
11
11
|
import { getMarkdownTheme } from "@earendil-works/pi-coding-agent";
|
|
12
12
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
13
|
-
import {
|
|
14
|
-
bindAgentSummary,
|
|
15
|
-
summaryMarkdown,
|
|
16
|
-
type AgentSummaryData,
|
|
17
|
-
} from "../utils/agent-summary.ts";
|
|
13
|
+
import { bindAgentSummary, summaryMarkdown, type AgentSummaryData } from "./core.ts";
|
|
18
14
|
|
|
19
15
|
export const AGENT_SUMMARY_ENTRY_TYPE = "agent-summary";
|
|
20
16
|
|
|
@@ -94,7 +94,7 @@ type AssistantInternals = {
|
|
|
94
94
|
};
|
|
95
95
|
|
|
96
96
|
type PatchedPrototype = typeof AssistantMessageComponent.prototype & {
|
|
97
|
-
updateContent: (message: AssistantMessage) => void;
|
|
97
|
+
updateContent: (message: AssistantMessage, isStreaming?: boolean) => void;
|
|
98
98
|
};
|
|
99
99
|
|
|
100
100
|
// 配置由 claude-code-style 管控(installCompactThinking 注入初始值,
|
|
@@ -334,9 +334,14 @@ function compactThinking(pi: ExtensionAPI) {
|
|
|
334
334
|
);
|
|
335
335
|
}
|
|
336
336
|
|
|
337
|
-
prototype.updateContent = function patchedUpdateContent(
|
|
337
|
+
prototype.updateContent = function patchedUpdateContent(
|
|
338
|
+
message: AssistantMessage,
|
|
339
|
+
isStreaming?: boolean,
|
|
340
|
+
) {
|
|
338
341
|
const component = this as AssistantMessageComponentLike;
|
|
339
342
|
const self = this as unknown as AssistantInternals;
|
|
343
|
+
// isStreaming 丢失 → mermaid 流式误渲染来回闪。
|
|
344
|
+
self.isStreaming = isStreaming ?? self.isStreaming;
|
|
340
345
|
self.lastMessage = message;
|
|
341
346
|
latestComponent = component;
|
|
342
347
|
latestComponentTimestamp = message.timestamp;
|
|
@@ -344,7 +349,7 @@ function compactThinking(pi: ExtensionAPI) {
|
|
|
344
349
|
// Visible mode is intentionally untouched: Shift+Tab restores Pi's exact
|
|
345
350
|
// built-in Thinking Markdown renderer, including every OpenAI summary stage.
|
|
346
351
|
if (!self.hideThinkingBlock) {
|
|
347
|
-
originalUpdateContent.call(this, message);
|
|
352
|
+
originalUpdateContent.call(this, message, self.isStreaming);
|
|
348
353
|
return;
|
|
349
354
|
}
|
|
350
355
|
|
|
@@ -184,7 +184,6 @@ export default function agentAutocompleteExtension(pi: ExtensionAPI): void {
|
|
|
184
184
|
|
|
185
185
|
const agentMap = new Map(agents.map((a) => [a.name, a]));
|
|
186
186
|
const agentList = mentions.map((n) => `"${n}" (${agentMap.get(n)!.displayName})`).join(", ");
|
|
187
|
-
const agentTypes = mentions.map((n) => `"${n}"`).join(" | ");
|
|
188
187
|
|
|
189
188
|
return {
|
|
190
189
|
systemPrompt:
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { VERSION, type AppKeybinding } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { getKeybindings } from "@earendil-works/pi-tui";
|
|
3
3
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
4
|
-
import { config } from "
|
|
5
|
-
|
|
4
|
+
import { config } from "../../config/config.ts";
|
|
5
|
+
import { ansi16ToRgb, ansi256ToRgb } from "../../utils/ansi-color.ts";
|
|
6
6
|
type Rgb = [number, number, number];
|
|
7
7
|
type StyledPart = {
|
|
8
8
|
raw: string;
|
|
@@ -40,25 +40,6 @@ const PALETTE_SPAN = 0.25;
|
|
|
40
40
|
// 行间相位偏移:小步累加 → 整体左上暗→右下亮的对角渐变
|
|
41
41
|
const LOGO_ROW_PHASE_STEP = 0.08;
|
|
42
42
|
|
|
43
|
-
const ANSI_16_RGB_TABLE: Rgb[] = [
|
|
44
|
-
[0, 0, 0],
|
|
45
|
-
[128, 0, 0],
|
|
46
|
-
[0, 128, 0],
|
|
47
|
-
[128, 128, 0],
|
|
48
|
-
[0, 0, 128],
|
|
49
|
-
[128, 0, 128],
|
|
50
|
-
[0, 128, 128],
|
|
51
|
-
[192, 192, 192],
|
|
52
|
-
[128, 128, 128],
|
|
53
|
-
[255, 0, 0],
|
|
54
|
-
[0, 255, 0],
|
|
55
|
-
[255, 255, 0],
|
|
56
|
-
[0, 0, 255],
|
|
57
|
-
[255, 0, 255],
|
|
58
|
-
[0, 255, 255],
|
|
59
|
-
[255, 255, 255],
|
|
60
|
-
];
|
|
61
|
-
|
|
62
43
|
function stripAnsi(text: string): string {
|
|
63
44
|
return text.replace(ANSI_PATTERN, "");
|
|
64
45
|
}
|
|
@@ -104,27 +85,6 @@ function applyTruecolor(rgb: Rgb, text: string): string {
|
|
|
104
85
|
return `\x1b[38;2;${red};${green};${blue}m${text}${ANSI_RESET}`;
|
|
105
86
|
}
|
|
106
87
|
|
|
107
|
-
function ansi16ToRgb(index: number): Rgb {
|
|
108
|
-
return ANSI_16_RGB_TABLE[index] ?? [255, 255, 255];
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
function ansi256ToRgb(index: number): Rgb {
|
|
112
|
-
if (index < 16) return ansi16ToRgb(index);
|
|
113
|
-
|
|
114
|
-
if (index >= 232) {
|
|
115
|
-
const gray = 8 + (index - 232) * 10;
|
|
116
|
-
return [gray, gray, gray];
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
const cubeIndex = index - 16;
|
|
120
|
-
const redIndex = Math.floor(cubeIndex / 36);
|
|
121
|
-
const greenIndex = Math.floor((cubeIndex % 36) / 6);
|
|
122
|
-
const blueIndex = cubeIndex % 6;
|
|
123
|
-
const values = [0, 95, 135, 175, 215, 255];
|
|
124
|
-
|
|
125
|
-
return [values[redIndex]!, values[greenIndex]!, values[blueIndex]!];
|
|
126
|
-
}
|
|
127
|
-
|
|
128
88
|
function parseTruecolorAnsi(ansi: string): Rgb | undefined {
|
|
129
89
|
const match = ansi.match(/38;2;(\d+);(\d+);(\d+)/);
|
|
130
90
|
if (!match) return undefined;
|
|
@@ -1,19 +1,10 @@
|
|
|
1
1
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { formatDuration } from "../../utils/format.ts";
|
|
2
3
|
|
|
3
4
|
const REFRESH_INTERVAL_MS = 1_000;
|
|
4
5
|
/** Elapsed time is only shown once the turn has run this long. */
|
|
5
6
|
const SHOW_TIMER_AFTER_MS = 3_000;
|
|
6
7
|
|
|
7
|
-
function formatDuration(ms: number): string {
|
|
8
|
-
const totalSec = Math.floor(ms / 1000);
|
|
9
|
-
const hours = Math.floor(totalSec / 3600);
|
|
10
|
-
const minutes = Math.floor((totalSec % 3600) / 60);
|
|
11
|
-
const seconds = totalSec % 60;
|
|
12
|
-
if (hours > 0) return `${hours}h ${minutes}m ${seconds}s`;
|
|
13
|
-
if (minutes > 0) return `${minutes}m ${seconds}s`;
|
|
14
|
-
return `${seconds}s`;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
8
|
function formatCount(value: number): string {
|
|
18
9
|
return new Intl.NumberFormat("en-US").format(value);
|
|
19
10
|
}
|
|
@@ -91,7 +82,10 @@ export default function (pi: ExtensionAPI): void {
|
|
|
91
82
|
const tokens = tokenCount();
|
|
92
83
|
const parts: string[] = [];
|
|
93
84
|
if (tokens > 0) parts.push(`↓ ${formatCount(tokens)} tokens`);
|
|
94
|
-
if (elapsed >= SHOW_TIMER_AFTER_MS || tokens > 0)
|
|
85
|
+
if (elapsed >= SHOW_TIMER_AFTER_MS || tokens > 0) {
|
|
86
|
+
// formatDuration 低于 1 秒返回 "",此处回退 "0s" 保持计时器连续跳动。
|
|
87
|
+
parts.push(formatDuration(elapsed) || "0s");
|
|
88
|
+
}
|
|
95
89
|
return parts.length ? `Working... (${parts.join(" · ")})` : "";
|
|
96
90
|
}
|
|
97
91
|
|
package/extensions/index.ts
CHANGED
|
@@ -1,45 +1,35 @@
|
|
|
1
1
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
import { config } from "./config/config.ts";
|
|
3
|
+
|
|
4
|
+
// shell
|
|
5
|
+
import piAliases from "./feature/shell/aliases.ts";
|
|
6
|
+
import piStartupHeader from "./feature/shell/startup-header.ts";
|
|
7
|
+
import workingMessage from "./feature/shell/working-message.ts";
|
|
8
|
+
|
|
9
|
+
// feature
|
|
10
|
+
import agentAutocomplete from "./feature/reference/subagent.ts";
|
|
11
|
+
import agentSummary from "./feature/agent-summary/index.ts";
|
|
9
12
|
import context from "./feature/context.ts";
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
import
|
|
13
|
+
import sessionReference from "./feature/reference/index.ts";
|
|
14
|
+
import { installCompactThinking } from "./feature/compact-thinking.ts";
|
|
15
|
+
|
|
16
|
+
// renderer
|
|
17
|
+
import claudeCodeStyle, { getCompactThinkingConfig } from "./renderer/index.ts";
|
|
18
|
+
import markdownEnhance from "./renderer/markdown-enhance.ts";
|
|
15
19
|
|
|
16
20
|
export default function (pi: ExtensionAPI): void {
|
|
17
|
-
|
|
21
|
+
// shell chrome
|
|
22
|
+
if (config.enableAliases) piAliases(pi);
|
|
18
23
|
piStartupHeader(pi);
|
|
24
|
+
if (config.enableWorkingMessage) workingMessage(pi);
|
|
25
|
+
|
|
26
|
+
// render stack:thinking controller 直接交给 style 作 query
|
|
19
27
|
markdownEnhance(pi);
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
},
|
|
28
|
-
isMessageThinkingActive(messageTimestamp) {
|
|
29
|
-
return compactThinking?.isMessageThinkingActive?.(messageTimestamp) ?? false;
|
|
30
|
-
},
|
|
31
|
-
getThinkingAnimationFrame() {
|
|
32
|
-
return compactThinking?.getThinkingAnimationFrame?.() ?? 0;
|
|
33
|
-
},
|
|
34
|
-
setCompactSummaryActive(active) {
|
|
35
|
-
compactThinking?.setCompactSummaryActive?.(active);
|
|
36
|
-
},
|
|
37
|
-
};
|
|
38
|
-
claudeCodeStyle(pi, undefined, compactThinkingBridge);
|
|
39
|
-
compactThinking = installCompactThinking(pi, getCompactThinkingConfig());
|
|
40
|
-
workingMessage(pi);
|
|
41
|
-
context(pi);
|
|
42
|
-
sessionReference(pi);
|
|
43
|
-
agentAutocomplete(pi);
|
|
44
|
-
agentSummary(pi);
|
|
28
|
+
claudeCodeStyle(pi, undefined, installCompactThinking(pi, getCompactThinkingConfig()));
|
|
29
|
+
|
|
30
|
+
// features
|
|
31
|
+
if (config.enableContextCommand) context(pi);
|
|
32
|
+
if (config.enableSessionReference) sessionReference(pi);
|
|
33
|
+
if (config.enableSubagentAutocomplete) agentAutocomplete(pi);
|
|
34
|
+
if (config.enableAgentSummary) agentSummary(pi);
|
|
45
35
|
}
|