@herbertgao/pi-extensions 2026.8.1 → 2026.8.2
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.md +5 -2
- package/node_modules/@czottmann/pi-automode/README.md +16 -2
- package/node_modules/@czottmann/pi-automode/docs/GLOSSARY.md +35 -0
- package/node_modules/@czottmann/pi-automode/docs/automode-classifier-flow.md +18 -9
- package/node_modules/@czottmann/pi-automode/docs/defaults.md +6 -2
- package/node_modules/@czottmann/pi-automode/examples/automode.local.json +6 -0
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/classifier.ts +11 -7
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/config.ts +100 -0
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/constants.ts +32 -0
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/extension.ts +78 -3
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/hard-deny.ts +16 -4
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/paths.ts +23 -1
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/permissions.ts +22 -1
- package/node_modules/@czottmann/pi-automode/extensions/auto-mode/types.ts +18 -2
- package/node_modules/@czottmann/pi-automode/package.json +4 -4
- package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-audit.md +5 -0
- package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-debt.md +5 -0
- package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-gain.md +5 -0
- package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-help.md +5 -0
- package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-review.md +5 -0
- package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail.md +5 -0
- package/node_modules/@dietrichgebert/ponytail/.opencode/plugins/ponytail-frontmatter.cjs +23 -0
- package/node_modules/@dietrichgebert/ponytail/.opencode/plugins/ponytail.mjs +99 -0
- package/node_modules/@dietrichgebert/ponytail/.qoder/rules/ponytail.md +30 -0
- package/node_modules/@dietrichgebert/ponytail/.qoder-plugin/plugin.json +16 -0
- package/node_modules/@dietrichgebert/ponytail/AGENTS.md +32 -0
- package/node_modules/@dietrichgebert/ponytail/LICENSE +21 -0
- package/node_modules/@dietrichgebert/ponytail/README.es.md +298 -0
- package/node_modules/@dietrichgebert/ponytail/README.ko.md +315 -0
- package/node_modules/@dietrichgebert/ponytail/README.md +351 -0
- package/node_modules/@dietrichgebert/ponytail/assets/benchmark-3model.svg +21 -0
- package/node_modules/@dietrichgebert/ponytail/assets/benchmark-agentic.svg +62 -0
- package/node_modules/@dietrichgebert/ponytail/assets/logo-dark.png +0 -0
- package/node_modules/@dietrichgebert/ponytail/assets/logo-dark.svg +115 -0
- package/node_modules/@dietrichgebert/ponytail/assets/logo-greenpt-dark.svg +27 -0
- package/node_modules/@dietrichgebert/ponytail/assets/logo-greenpt.svg +27 -0
- package/node_modules/@dietrichgebert/ponytail/assets/logo.png +0 -0
- package/node_modules/@dietrichgebert/ponytail/assets/social-preview.png +0 -0
- package/node_modules/@dietrichgebert/ponytail/assets/waitlist-banner-es.png +0 -0
- package/node_modules/@dietrichgebert/ponytail/assets/waitlist-banner-ko.png +0 -0
- package/node_modules/@dietrichgebert/ponytail/assets/waitlist-banner.png +0 -0
- package/node_modules/@dietrichgebert/ponytail/hooks/claude-codex-hooks.json +44 -0
- package/node_modules/@dietrichgebert/ponytail/hooks/copilot-hooks.json +21 -0
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-activate.js +96 -0
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-config.js +169 -0
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-instructions.js +98 -0
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-mode-tracker.js +130 -0
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-runtime.js +85 -0
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-statusline.ps1 +24 -0
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-statusline.sh +18 -0
- package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-subagent.js +77 -0
- package/node_modules/@dietrichgebert/ponytail/hooks/qoder-hooks.json +26 -0
- package/node_modules/@dietrichgebert/ponytail/package.json +47 -0
- package/node_modules/@dietrichgebert/ponytail/pi-extension/index.js +211 -0
- package/node_modules/@dietrichgebert/ponytail/pi-extension/package.json +8 -0
- package/node_modules/@dietrichgebert/ponytail/scripts/uninstall.js +60 -0
- package/node_modules/@dietrichgebert/ponytail/skills/ponytail/SKILL.md +120 -0
- package/node_modules/@dietrichgebert/ponytail/skills/ponytail-audit/SKILL.md +41 -0
- package/node_modules/@dietrichgebert/ponytail/skills/ponytail-debt/SKILL.md +44 -0
- package/node_modules/@dietrichgebert/ponytail/skills/ponytail-gain/SKILL.md +50 -0
- package/node_modules/@dietrichgebert/ponytail/skills/ponytail-help/SKILL.md +71 -0
- package/node_modules/@dietrichgebert/ponytail/skills/ponytail-review/SKILL.md +57 -0
- package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +1 -3
- package/node_modules/@herbertgao/pi-cc-extensions/README.md +1 -3
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +10 -6
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/agent-summary.ts +6 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/compact-thinking.ts +24 -83
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/context.ts +1 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/markdown-enhance.ts +119 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +73 -9
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/index.ts +2 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse-hover.ts +130 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse-interaction.ts +65 -542
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse-layout.ts +160 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse-packets.ts +143 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse-scroll.ts +184 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool-diff/diff-renderer.ts +2 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool-grouping.ts +9 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/transcript-refresh.ts +91 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/utils/agent-summary.ts +1 -1
- package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
- package/node_modules/@herbertgao/pi-cc-extensions/themes/cc-dark.json +1 -0
- package/node_modules/@herbertgao/pi-cc-extensions/themes/cc-light.json +2 -2
- package/node_modules/@herbertgao/pi-stash/README.md +9 -9
- package/node_modules/@herbertgao/pi-stash/package.json +1 -1
- package/node_modules/@herbertgao/pi-stash/src/index.ts +2 -1
- package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +14 -0
- package/node_modules/@herbertgao/pi-subagents/README.md +6 -2
- package/node_modules/@herbertgao/pi-subagents/package.json +3 -3
- package/node_modules/@herbertgao/pi-subagents/src/custom-agents.ts +85 -11
- package/node_modules/@herbertgao/pi-subagents/src/index.ts +28 -4
- package/node_modules/@herbertgao/pi-subagents/src/settings.ts +12 -0
- package/node_modules/@herbertgao/pi-subagents/src/types.ts +2 -0
- package/node_modules/@narumitw/pi-btw/LICENSE +21 -0
- package/node_modules/@narumitw/pi-btw/README.md +210 -0
- package/node_modules/@narumitw/pi-btw/package.json +53 -0
- package/node_modules/@narumitw/pi-btw/src/bring-to-main.ts +632 -0
- package/node_modules/@narumitw/pi-btw/src/btw.ts +996 -0
- package/node_modules/@narumitw/pi-btw/src/fullscreen-ui.ts +339 -0
- package/node_modules/@narumitw/pi-btw/src/index.ts +1 -0
- package/node_modules/@narumitw/pi-btw/src/menu.ts +296 -0
- package/node_modules/@narumitw/pi-btw/src/settings.ts +237 -0
- package/node_modules/@narumitw/pi-btw/src/side-thread.ts +238 -0
- package/node_modules/@narumitw/pi-btw/src/text.ts +10 -0
- package/node_modules/@narumitw/pi-btw/src/transcript-pager.ts +620 -0
- package/node_modules/@pi-plugins/fast-mode/LICENSE +21 -0
- package/node_modules/@pi-plugins/fast-mode/README.md +92 -0
- package/node_modules/@pi-plugins/fast-mode/dist/index.d.mts +6 -0
- package/node_modules/@pi-plugins/fast-mode/dist/index.d.mts.map +1 -0
- package/node_modules/@pi-plugins/fast-mode/dist/index.mjs +2026 -0
- package/node_modules/@pi-plugins/fast-mode/dist/index.mjs.map +1 -0
- package/node_modules/@pi-plugins/fast-mode/package.json +73 -0
- package/node_modules/pi-mcp-adapter/CHANGELOG.md +59 -0
- package/node_modules/pi-mcp-adapter/README.md +62 -13
- package/node_modules/pi-mcp-adapter/agent-plugin-loader.ts +377 -0
- package/node_modules/pi-mcp-adapter/commands.ts +9 -7
- package/node_modules/pi-mcp-adapter/config.ts +110 -49
- package/node_modules/pi-mcp-adapter/direct-tools.ts +34 -19
- package/node_modules/pi-mcp-adapter/elicitation-handler.ts +37 -36
- package/node_modules/pi-mcp-adapter/errors.ts +21 -17
- package/node_modules/pi-mcp-adapter/host-html-template.ts +13 -7
- package/node_modules/pi-mcp-adapter/index.ts +37 -14
- package/node_modules/pi-mcp-adapter/init.ts +9 -7
- package/node_modules/pi-mcp-adapter/json-schema-validator.ts +2 -2
- package/node_modules/pi-mcp-adapter/lifecycle.ts +8 -8
- package/node_modules/pi-mcp-adapter/logger.ts +1 -1
- package/node_modules/pi-mcp-adapter/mcp-auth-flow.ts +36 -22
- package/node_modules/pi-mcp-adapter/mcp-auth.ts +120 -2
- package/node_modules/pi-mcp-adapter/mcp-code.ts +13 -11
- package/node_modules/pi-mcp-adapter/mcp-oauth-provider.ts +19 -13
- package/node_modules/pi-mcp-adapter/mcp-output-guard.ts +15 -11
- package/node_modules/pi-mcp-adapter/mcp-panel.ts +34 -15
- package/node_modules/pi-mcp-adapter/mcp-probe.ts +131 -34
- package/node_modules/pi-mcp-adapter/mcp-script-worker.mjs +2 -2
- package/node_modules/pi-mcp-adapter/mcp-setup-panel.ts +7 -4
- package/node_modules/pi-mcp-adapter/mcp-trace.ts +59 -64
- package/node_modules/pi-mcp-adapter/metadata-cache.ts +34 -26
- package/node_modules/pi-mcp-adapter/npx-resolver.ts +6 -4
- package/node_modules/pi-mcp-adapter/oauth-handler.ts +1 -1
- package/node_modules/pi-mcp-adapter/onboarding-state.ts +19 -11
- package/node_modules/pi-mcp-adapter/package.json +13 -8
- package/node_modules/pi-mcp-adapter/panel-keys.ts +20 -4
- package/node_modules/pi-mcp-adapter/prompts.ts +2 -2
- package/node_modules/pi-mcp-adapter/proxy-modes.ts +48 -11
- package/node_modules/pi-mcp-adapter/sampling-handler.ts +22 -15
- package/node_modules/pi-mcp-adapter/search-ranking.ts +2 -1
- package/node_modules/pi-mcp-adapter/server-manager.ts +165 -113
- package/node_modules/pi-mcp-adapter/session-recovery.ts +11 -12
- package/node_modules/pi-mcp-adapter/skills/mcp-scripting/SKILL.md +3 -3
- package/node_modules/pi-mcp-adapter/state.ts +3 -1
- package/node_modules/pi-mcp-adapter/tool-approval.ts +67 -4
- package/node_modules/pi-mcp-adapter/tool-metadata.ts +6 -5
- package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +14 -2
- package/node_modules/pi-mcp-adapter/ts-shape.ts +9 -2
- package/node_modules/pi-mcp-adapter/types.ts +109 -22
- package/node_modules/pi-mcp-adapter/ui-app-bridge-helpers.ts +40 -0
- package/node_modules/pi-mcp-adapter/ui-resource-handler.ts +28 -19
- package/node_modules/pi-mcp-adapter/ui-server.ts +90 -58
- package/node_modules/pi-mcp-adapter/ui-session.ts +16 -14
- package/node_modules/pi-mcp-adapter/unix-socket-transport.ts +4 -4
- package/node_modules/pi-mcp-adapter/utils.ts +23 -9
- package/package.json +22 -7
|
@@ -38,7 +38,7 @@ Run `/reload` after installation.
|
|
|
38
38
|
| Feature | Description | Entry point |
|
|
39
39
|
| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
|
|
40
40
|
| Claude Code-style output | Tool summaries, expand/collapse, rich edit/write diffs, and`on` / `compact` / `off` modes | `/ccstyle` |
|
|
41
|
-
| Fullscreen mouse interaction | Tool card/group click-to-toggle,
|
|
41
|
+
| Fullscreen mouse interaction | Tool card/group click-to-toggle, previews, hover highlight, and a back-to-bottom button | `TUIMODE=fullscreen` or `--tui-mode fullscreen` |
|
|
42
42
|
| Settings panel | `Style / Diff / Thinking / Feature` tabs: startup header toggle and wheel step | `/ccstyle` |
|
|
43
43
|
| Context inspection | Usage breakdown and previews for the system prompt, tools, skills, and messages | `/context` |
|
|
44
44
|
| Session references | Search and inject effective context from previous Sessions or existing SubAgents | `@session:` |
|
|
@@ -79,8 +79,6 @@ Run `/reload` after changing extensions.
|
|
|
79
79
|
## Compatibility
|
|
80
80
|
|
|
81
81
|
- Node.js `>=22.19.0`, Pi `^0.84.0` (loaded through `pi.extensions` and `pi.themes` in the root `package.json`)
|
|
82
|
-
- Fixed-editor features have moved to the official pipeline. `/ccstyle` mouse interactions remain available in TUI fullscreen mode.
|
|
83
|
-
- Use version `0.8.46` or earlier only if you need the removed fixed-editor layout.
|
|
84
82
|
|
|
85
83
|
## Recommended companions
|
|
86
84
|
|
|
@@ -38,7 +38,7 @@ pi install npm:@herbertgao/pi-cc-extensions
|
|
|
38
38
|
| 功能 | 说明 | 入口 |
|
|
39
39
|
| ---------------------- | ---------------------------------------------------------------------------------------------------------- | ------------- |
|
|
40
40
|
| Claude Code 风格输出 | 工具摘要、折叠展开、rich edit/write diff,以及`on` / `compact` / `off` 三种模式 | `/ccstyle` |
|
|
41
|
-
| Fullscreen 鼠标交互 | 工具卡/group 点击展开与收起、预览、hover
|
|
41
|
+
| Fullscreen 鼠标交互 | 工具卡/group 点击展开与收起、预览、hover 高亮、回到底部按钮 | `TUIMODE=fullscreen` 或 `--tui-mode fullscreen` |
|
|
42
42
|
| 配置面板 | `Style / Diff / Thinking / Feature` 四页签,含启动头开关与滚轮步进 | `/ccstyle` |
|
|
43
43
|
| 上下文检查 | 查看上下文占用,并预览 System prompt、Tools、Skills 和消息内容 | `/context` |
|
|
44
44
|
| Session 引用 | 搜索并注入历史 Session 或现有 SubAgent 的有效上下文 | `@session:` |
|
|
@@ -79,8 +79,6 @@ bun run typecheck
|
|
|
79
79
|
## 兼容性
|
|
80
80
|
|
|
81
81
|
- Node.js `>=22.19.0`,Pi `^0.84.0`(通过根目录 `package.json` 的 `pi.extensions` 和 `pi.themes` 加载)
|
|
82
|
-
- fixed-editor 相关功能已迁移至官方管线:TUI mode=fullscreen 模式下 `/ccstyle` 鼠标交互仍可用。
|
|
83
|
-
- 需要已移除的 fixed-editor 布局时,请使用 `0.8.46` 及更早版本。
|
|
84
82
|
|
|
85
83
|
## 推荐搭配
|
|
86
84
|
|
|
@@ -38,7 +38,7 @@ export type CcstylePanelHooks = {
|
|
|
38
38
|
|
|
39
39
|
function modeSettingDescription(mode: CompactStyleMode): string {
|
|
40
40
|
if (mode === "compact") {
|
|
41
|
-
return "One summary line per assistant round; expanded edit/write rows show rich diffs.";
|
|
41
|
+
return "(Experimental) One summary line per assistant round; expanded edit/write rows show rich diffs.";
|
|
42
42
|
}
|
|
43
43
|
if (mode === "off") {
|
|
44
44
|
return "Pi native tool rendering. Diff options below still apply independently.";
|
|
@@ -209,8 +209,8 @@ export async function showCcstylePanel(
|
|
|
209
209
|
id: "mode",
|
|
210
210
|
label: "Mode",
|
|
211
211
|
description: modeSettingDescription(config.mode),
|
|
212
|
-
currentValue: config.mode,
|
|
213
|
-
values: ["on", "compact", "off"],
|
|
212
|
+
currentValue: config.mode === "compact" ? "compact (Experimental)" : config.mode,
|
|
213
|
+
values: ["on", "compact (Experimental)", "off"],
|
|
214
214
|
};
|
|
215
215
|
// Tracks whether the Exclude-tools submenu is open so Tab switches sections
|
|
216
216
|
// only at the top level (mirrors Zentui settings: Tab = switch sections).
|
|
@@ -336,10 +336,14 @@ export async function showCcstylePanel(
|
|
|
336
336
|
|
|
337
337
|
const onSettingChange = (id: string, value: string) => {
|
|
338
338
|
switch (id) {
|
|
339
|
-
case "mode":
|
|
340
|
-
|
|
341
|
-
|
|
339
|
+
case "mode": {
|
|
340
|
+
// 选项值带 Experimental 标记,选择后还原为真实 mode 值。
|
|
341
|
+
const mode: CompactStyleMode =
|
|
342
|
+
value === "compact (Experimental)" ? "compact" : (value as CompactStyleMode);
|
|
343
|
+
modeSetting.description = modeSettingDescription(mode);
|
|
344
|
+
hooks.applyStyleMode(mode, ctx, toolGrouping);
|
|
342
345
|
return;
|
|
346
|
+
}
|
|
343
347
|
case "excludeRenderers":
|
|
344
348
|
excludeSetting.currentValue = formatExcludeRenderers(config.excludeRenderers);
|
|
345
349
|
excludeSetting.description = excludeRenderersDescription(config.excludeRenderers);
|
|
@@ -10,13 +10,17 @@
|
|
|
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 {
|
|
13
|
+
import {
|
|
14
|
+
bindAgentSummary,
|
|
15
|
+
summaryMarkdown,
|
|
16
|
+
type AgentSummaryData,
|
|
17
|
+
} from "../utils/agent-summary.ts";
|
|
14
18
|
|
|
15
19
|
export const AGENT_SUMMARY_ENTRY_TYPE = "agent-summary";
|
|
16
20
|
|
|
17
21
|
export default function (pi: ExtensionAPI): void {
|
|
18
22
|
pi.registerEntryRenderer(AGENT_SUMMARY_ENTRY_TYPE, (entry, _options, theme) => {
|
|
19
|
-
const line = summaryMarkdown(entry.data, true, {
|
|
23
|
+
const line = summaryMarkdown(entry.data as AgentSummaryData, true, {
|
|
20
24
|
success: theme.getFgAnsi("success"),
|
|
21
25
|
failed: theme.getFgAnsi("error"),
|
|
22
26
|
});
|
|
@@ -13,6 +13,14 @@ import {
|
|
|
13
13
|
} from "@earendil-works/pi-coding-agent";
|
|
14
14
|
import { getKeybindings } from "@earendil-works/pi-tui";
|
|
15
15
|
import { Markdown, Spacer, Text, type Component } from "@earendil-works/pi-tui";
|
|
16
|
+
import {
|
|
17
|
+
animateCompactThinkingText,
|
|
18
|
+
formatThoughtDuration,
|
|
19
|
+
styleCompactThinkingText,
|
|
20
|
+
} from "../renderer/compact-mode.ts";
|
|
21
|
+
import { refreshMountedTranscript } from "../renderer/transcript-refresh.ts";
|
|
22
|
+
// 保持导出兼容:渲染函数已并入 renderer/compact-mode.ts,这里 re-export。
|
|
23
|
+
export { animateCompactThinkingText, formatThoughtDuration, styleCompactThinkingText };
|
|
16
24
|
|
|
17
25
|
// pi-tui 类型声明中 TUI 的 re-export 解析失败,本地用最小结构化类型(只用到 requestRender)。
|
|
18
26
|
type RenderTui = { requestRender(force?: boolean): void };
|
|
@@ -146,70 +154,6 @@ function restoreDurationEntries(
|
|
|
146
154
|
}
|
|
147
155
|
}
|
|
148
156
|
|
|
149
|
-
function formatThoughtDuration(durationMs: number) {
|
|
150
|
-
if (durationMs < 1_000) {
|
|
151
|
-
return `${Math.max(1, Math.round(durationMs))}ms`;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
const totalSeconds = Math.max(1, Math.round(durationMs / 1_000));
|
|
155
|
-
const minutes = Math.floor(totalSeconds / 60);
|
|
156
|
-
const seconds = totalSeconds % 60;
|
|
157
|
-
if (minutes === 0) return `${seconds}s`;
|
|
158
|
-
return seconds === 0 ? `${minutes}m` : `${minutes}m ${seconds}s`;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
export { formatThoughtDuration };
|
|
162
|
-
|
|
163
|
-
type CompactThinkingTheme = Pick<Theme, "fg" | "italic" | "bold">;
|
|
164
|
-
|
|
165
|
-
/** 与 compact-thinking 主渲染器共用的静态文字样式。 */
|
|
166
|
-
export function styleCompactThinkingText(
|
|
167
|
-
text: string,
|
|
168
|
-
theme: CompactThinkingTheme | undefined,
|
|
169
|
-
bold = false,
|
|
170
|
-
): string {
|
|
171
|
-
if (!theme) return text;
|
|
172
|
-
const colored = typeof theme.fg === "function" ? theme.fg("thinkingText", text) : text;
|
|
173
|
-
const weighted = bold && typeof theme.bold === "function" ? theme.bold(colored) : colored;
|
|
174
|
-
return typeof theme.italic === "function" ? theme.italic(weighted) : weighted;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/** 与 compact-thinking 主渲染器共用的活动思考扫光动画。 */
|
|
178
|
-
export function animateCompactThinkingText(
|
|
179
|
-
text: string,
|
|
180
|
-
theme: CompactThinkingTheme | undefined,
|
|
181
|
-
animationFrame: number,
|
|
182
|
-
boldBase = false,
|
|
183
|
-
): string {
|
|
184
|
-
if (!theme) return text;
|
|
185
|
-
const characters = Array.from(text);
|
|
186
|
-
if (characters.length === 0) return "";
|
|
187
|
-
const highlightWidth = Math.max(1, Math.min(5, Math.ceil(characters.length * 0.28)));
|
|
188
|
-
const start = (animationFrame % (characters.length + highlightWidth)) - highlightWidth;
|
|
189
|
-
const end = start + highlightWidth;
|
|
190
|
-
const before = characters.slice(0, Math.max(0, start)).join("");
|
|
191
|
-
const highlighted = characters
|
|
192
|
-
.slice(Math.max(0, start), Math.min(characters.length, end))
|
|
193
|
-
.join("");
|
|
194
|
-
const after = characters.slice(Math.max(0, end)).join("");
|
|
195
|
-
const highlightedColored =
|
|
196
|
-
highlighted && typeof theme.fg === "function" ? theme.fg("text", highlighted) : highlighted;
|
|
197
|
-
const highlightedWeighted =
|
|
198
|
-
highlightedColored && typeof theme.bold === "function"
|
|
199
|
-
? theme.bold(highlightedColored)
|
|
200
|
-
: highlightedColored;
|
|
201
|
-
const highlightedText =
|
|
202
|
-
highlightedWeighted && typeof theme.italic === "function"
|
|
203
|
-
? theme.italic(highlightedWeighted)
|
|
204
|
-
: highlightedWeighted;
|
|
205
|
-
|
|
206
|
-
return (
|
|
207
|
-
styleCompactThinkingText(before, theme, boldBase) +
|
|
208
|
-
highlightedText +
|
|
209
|
-
styleCompactThinkingText(after, theme, boldBase)
|
|
210
|
-
);
|
|
211
|
-
}
|
|
212
|
-
|
|
213
157
|
function getThinkingToggleHint() {
|
|
214
158
|
const keys = getKeybindings().getKeys("app.thinking.toggle");
|
|
215
159
|
return keys.length > 0 ? `${keys.join("/")} to expand` : undefined;
|
|
@@ -343,7 +287,6 @@ function compactThinking(pi: ExtensionAPI) {
|
|
|
343
287
|
};
|
|
344
288
|
|
|
345
289
|
const completedDurations = new Map<number, Map<number, number>>();
|
|
346
|
-
const renderedComponents = new Set<AssistantMessageComponentLike>();
|
|
347
290
|
const streamingComponents = new Set<AssistantMessageComponentLike>();
|
|
348
291
|
let activeThinking: ActiveThinking | undefined;
|
|
349
292
|
let activeTheme: Theme | undefined;
|
|
@@ -355,14 +298,6 @@ function compactThinking(pi: ExtensionAPI) {
|
|
|
355
298
|
let compactSummaryActive = false;
|
|
356
299
|
let patchInstalled = true;
|
|
357
300
|
|
|
358
|
-
function refreshRenderedComponents() {
|
|
359
|
-
for (const component of renderedComponents) {
|
|
360
|
-
const self = component as unknown as AssistantInternals;
|
|
361
|
-
if (self.lastMessage) self.updateContent(self.lastMessage);
|
|
362
|
-
}
|
|
363
|
-
activeTui?.requestRender(true);
|
|
364
|
-
}
|
|
365
|
-
|
|
366
301
|
function thinkingStyle(text: string) {
|
|
367
302
|
return styleCompactThinkingText(text, activeTheme);
|
|
368
303
|
}
|
|
@@ -403,7 +338,6 @@ function compactThinking(pi: ExtensionAPI) {
|
|
|
403
338
|
const component = this as AssistantMessageComponentLike;
|
|
404
339
|
const self = this as unknown as AssistantInternals;
|
|
405
340
|
self.lastMessage = message;
|
|
406
|
-
renderedComponents.add(component);
|
|
407
341
|
latestComponent = component;
|
|
408
342
|
latestComponentTimestamp = message.timestamp;
|
|
409
343
|
|
|
@@ -512,8 +446,10 @@ function compactThinking(pi: ExtensionAPI) {
|
|
|
512
446
|
(durationText ? thinkingStyle(` · ${durationText}`) : "");
|
|
513
447
|
} else {
|
|
514
448
|
// Completed compact blocks use one provider-independent status line.
|
|
449
|
+
// 无时长记录(中断流/旧会话/entry 缺失或索引错位)时不回退到加载文案
|
|
450
|
+
// "Thinking...":改用摘要标题或中性 "Thought"。
|
|
515
451
|
heading = thinkingStyle(
|
|
516
|
-
durationText ? `Thought for ${durationText}` :
|
|
452
|
+
durationText ? `Thought for ${durationText}` : (latestSummary?.title ?? "Thought"),
|
|
517
453
|
);
|
|
518
454
|
}
|
|
519
455
|
self.contentContainer.addChild(new Text(heading, self.outputPad, 0));
|
|
@@ -684,7 +620,7 @@ function compactThinking(pi: ExtensionAPI) {
|
|
|
684
620
|
content?.type === "toolCall" &&
|
|
685
621
|
(content.name === "Agent" ||
|
|
686
622
|
content.name === "Agents" ||
|
|
687
|
-
content.
|
|
623
|
+
content.arguments?.subagent_type != null),
|
|
688
624
|
)
|
|
689
625
|
);
|
|
690
626
|
}
|
|
@@ -728,7 +664,9 @@ function compactThinking(pi: ExtensionAPI) {
|
|
|
728
664
|
// OpenAI-compatible providers may not close reasoning until the response ends.
|
|
729
665
|
pi.on("tool_execution_start", (event: any) => {
|
|
730
666
|
if (event.toolName === "Agent" || event.toolName === "Agents") {
|
|
731
|
-
|
|
667
|
+
const lastMessage = (latestComponent as unknown as { lastMessage?: AssistantMessage })
|
|
668
|
+
?.lastMessage;
|
|
669
|
+
resumeAgentThinking(lastMessage);
|
|
732
670
|
} else {
|
|
733
671
|
finishThinking();
|
|
734
672
|
}
|
|
@@ -751,20 +689,24 @@ function compactThinking(pi: ExtensionAPI) {
|
|
|
751
689
|
|
|
752
690
|
// An empty widget gives the animation loop access to requestRender without
|
|
753
691
|
// enabling terminal mouse reporting or intercepting native scrollback input.
|
|
692
|
+
// setWidget 的 factory 同步执行,此刻补丁已安装。
|
|
754
693
|
ctx.ui.setWidget(WIDGET_ID, (tui) => {
|
|
755
694
|
activeTui = tui;
|
|
756
695
|
return { render: () => [], invalidate() {} };
|
|
757
696
|
});
|
|
758
697
|
|
|
759
|
-
//
|
|
760
|
-
//
|
|
761
|
-
//
|
|
762
|
-
|
|
698
|
+
// pi 在 reload/resume 时先于 session_start 用原始原型重建聊天组件
|
|
699
|
+
// (rebuildChatFromMessages / renderCurrentSessionState)。由共享的
|
|
700
|
+
// refreshMountedTranscript 扫描挂载树重绘这些组件,恢复 compact 渲染、
|
|
701
|
+
// 持久化时长与工具调用显示。
|
|
702
|
+
refreshMountedTranscript(activeTui);
|
|
703
|
+
activeTui?.requestRender(true);
|
|
763
704
|
});
|
|
764
705
|
|
|
765
706
|
pi.on("session_tree", (_event, ctx) => {
|
|
766
707
|
restoreDurationEntries(ctx.sessionManager.getBranch(), completedDurations);
|
|
767
|
-
|
|
708
|
+
refreshMountedTranscript(activeTui);
|
|
709
|
+
activeTui?.requestRender(true);
|
|
768
710
|
});
|
|
769
711
|
|
|
770
712
|
pi.on("session_shutdown", (_event, ctx) => {
|
|
@@ -781,7 +723,6 @@ function compactThinking(pi: ExtensionAPI) {
|
|
|
781
723
|
latestComponent = undefined;
|
|
782
724
|
latestComponentTimestamp = undefined;
|
|
783
725
|
completedDurations.clear();
|
|
784
|
-
renderedComponents.clear();
|
|
785
726
|
streamingComponents.clear();
|
|
786
727
|
if (ctx.mode === "tui") ctx.ui.setWidget(WIDGET_ID, undefined);
|
|
787
728
|
|
|
@@ -639,7 +639,7 @@ export default function contextUsageExtension(pi: ExtensionAPI) {
|
|
|
639
639
|
);
|
|
640
640
|
|
|
641
641
|
if (!action) break;
|
|
642
|
-
const preview = previewByKey.get(action);
|
|
642
|
+
const preview = previewByKey.get(action as PreviewKey);
|
|
643
643
|
if (!preview) continue;
|
|
644
644
|
|
|
645
645
|
await showTextPreview(ctx, preview.title, preview.content);
|
|
@@ -129,6 +129,123 @@ function linkifyUrls(markdown: string): string {
|
|
|
129
129
|
return out.join("\n");
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
+
// ============================================================================
|
|
133
|
+
// 圈数字 → 半角括号
|
|
134
|
+
// ============================================================================
|
|
135
|
+
|
|
136
|
+
// Nerd Font 补丁字形(U+2460-U+2473)ink 超界,DirectWrite 下渲染会压住相邻字符;
|
|
137
|
+
// 转成 ASCII "(n)" 后任何字体下宽度一致。U+2460-U+2473 连续,差值即序号。
|
|
138
|
+
const CIRCLED_RE = /[①-⑳]/g;
|
|
139
|
+
const BLOCKQUOTE_PREFIX = /^ {0,3}>[ \t]?/;
|
|
140
|
+
const CODE_FENCE_OPEN = /^ {0,3}(`{3,}|~{3,})/;
|
|
141
|
+
const CODE_FENCE_CLOSE = /^ {0,3}(`+|~+)[ \t]*$/;
|
|
142
|
+
|
|
143
|
+
type FenceLine = { blockquoteDepth: number; content: string };
|
|
144
|
+
|
|
145
|
+
function parseFenceLine(line: string): FenceLine {
|
|
146
|
+
let content = line;
|
|
147
|
+
let blockquoteDepth = 0;
|
|
148
|
+
while (BLOCKQUOTE_PREFIX.test(content)) {
|
|
149
|
+
content = content.replace(BLOCKQUOTE_PREFIX, "");
|
|
150
|
+
blockquoteDepth++;
|
|
151
|
+
}
|
|
152
|
+
return { blockquoteDepth, content };
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function replaceCircled(text: string): string {
|
|
156
|
+
return text.replace(CIRCLED_RE, (ch) => `(${ch.codePointAt(0)! - 0x2460 + 1})`);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function backtickRunAt(
|
|
160
|
+
text: string,
|
|
161
|
+
start: number,
|
|
162
|
+
skipEscaped: boolean,
|
|
163
|
+
): { start: number; end: number } | null {
|
|
164
|
+
let index = text.indexOf("`", start);
|
|
165
|
+
while (index >= 0) {
|
|
166
|
+
let backslashes = 0;
|
|
167
|
+
for (let cursor = index - 1; cursor >= 0 && text[cursor] === "\\"; cursor--) backslashes++;
|
|
168
|
+
if (!skipEscaped || backslashes % 2 === 0) {
|
|
169
|
+
let end = index + 1;
|
|
170
|
+
while (text[end] === "`") end++;
|
|
171
|
+
return { start: index, end };
|
|
172
|
+
}
|
|
173
|
+
index = text.indexOf("`", index + 1);
|
|
174
|
+
}
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/** 转换连续 prose(可跨行),但保留有效 inline code spans。 */
|
|
179
|
+
function deCircledProse(prose: string): string {
|
|
180
|
+
let cursor = 0;
|
|
181
|
+
let transformed = "";
|
|
182
|
+
while (cursor < prose.length) {
|
|
183
|
+
const opening = backtickRunAt(prose, cursor, true);
|
|
184
|
+
if (!opening) {
|
|
185
|
+
transformed += replaceCircled(prose.slice(cursor));
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
let closing = backtickRunAt(prose, opening.end, false);
|
|
189
|
+
while (closing && closing.end - closing.start !== opening.end - opening.start) {
|
|
190
|
+
closing = backtickRunAt(prose, closing.end, false);
|
|
191
|
+
}
|
|
192
|
+
if (!closing) {
|
|
193
|
+
transformed += replaceCircled(prose.slice(cursor, opening.end));
|
|
194
|
+
cursor = opening.end;
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
transformed += replaceCircled(prose.slice(cursor, opening.start));
|
|
198
|
+
transformed += prose.slice(opening.start, closing.end);
|
|
199
|
+
cursor = closing.end;
|
|
200
|
+
}
|
|
201
|
+
return transformed;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/** 转换普通 Markdown 文本,但保留匹配 container 的 fenced blocks 与 inline code spans。 */
|
|
205
|
+
function deCircled(markdown: string): string {
|
|
206
|
+
const output: string[] = [];
|
|
207
|
+
let prose: string[] = [];
|
|
208
|
+
let fence: { marker: string; blockquoteDepth: number } | undefined;
|
|
209
|
+
const flushProse = () => {
|
|
210
|
+
if (prose.length === 0) return;
|
|
211
|
+
output.push(deCircledProse(prose.join("\n")));
|
|
212
|
+
prose = [];
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
for (const line of markdown.split("\n")) {
|
|
216
|
+
const parsed = parseFenceLine(line);
|
|
217
|
+
if (fence && parsed.blockquoteDepth >= fence.blockquoteDepth) {
|
|
218
|
+
output.push(line);
|
|
219
|
+
const close = parsed.content.match(CODE_FENCE_CLOSE)?.[1];
|
|
220
|
+
if (
|
|
221
|
+
parsed.blockquoteDepth === fence.blockquoteDepth &&
|
|
222
|
+
close?.[0] === fence.marker[0] &&
|
|
223
|
+
close.length >= fence.marker.length
|
|
224
|
+
) {
|
|
225
|
+
fence = undefined;
|
|
226
|
+
}
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
fence = undefined;
|
|
230
|
+
|
|
231
|
+
if (parsed.content.trim() === "") {
|
|
232
|
+
flushProse();
|
|
233
|
+
output.push(line);
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
const open = parsed.content.match(CODE_FENCE_OPEN)?.[1];
|
|
237
|
+
if (open) {
|
|
238
|
+
flushProse();
|
|
239
|
+
fence = { marker: open, blockquoteDepth: parsed.blockquoteDepth };
|
|
240
|
+
output.push(line);
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
243
|
+
prose.push(line);
|
|
244
|
+
}
|
|
245
|
+
flushProse();
|
|
246
|
+
return output.join("\n");
|
|
247
|
+
}
|
|
248
|
+
|
|
132
249
|
// ============================================================================
|
|
133
250
|
// 注册
|
|
134
251
|
// ============================================================================
|
|
@@ -140,6 +257,8 @@ export default function (pi: ExtensionAPI): void {
|
|
|
140
257
|
const { messageType, isStreaming = false } = context ?? {};
|
|
141
258
|
// 与官方推荐一致:thinking 块与流式中间态不转换
|
|
142
259
|
if (messageType === "assistant-thinking" || isStreaming) return markdown;
|
|
260
|
+
// 0. 圈数字转半角括号(Nerd Font 补丁字形缺陷规避)
|
|
261
|
+
markdown = deCircled(markdown);
|
|
143
262
|
// 1. Mermaid 方言渲染
|
|
144
263
|
markdown = renderDiagrams(markdown, context);
|
|
145
264
|
// 2. GitHub 风格提示框
|
|
@@ -12,17 +12,17 @@
|
|
|
12
12
|
* 补丁生命周期遵循仓库既有模式:Symbol 所有权、dispose 仅恢复仍由本安装持有的
|
|
13
13
|
* 方法、重入守卫防止 /reload 后残留闭包递归。
|
|
14
14
|
*/
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
AssistantMessageComponent,
|
|
17
|
+
ToolExecutionComponent,
|
|
18
|
+
type Theme,
|
|
19
|
+
} from "@earendil-works/pi-coding-agent";
|
|
16
20
|
import * as PiTui from "@earendil-works/pi-tui";
|
|
17
21
|
import { truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
18
22
|
import { config, getToolDisplayConfig } from "../config/config.ts";
|
|
19
|
-
import {
|
|
20
|
-
animateCompactThinkingText,
|
|
21
|
-
formatThoughtDuration,
|
|
22
|
-
styleCompactThinkingText,
|
|
23
|
-
} from "../feature/compact-thinking.ts";
|
|
24
23
|
import { toolLoadingIcon } from "../utils/tool-loading-icon.ts";
|
|
25
24
|
import { sanitizeToolResultText } from "../utils/tool-result-sanitize.ts";
|
|
25
|
+
import { refreshTranscriptComponent } from "./transcript-refresh.ts";
|
|
26
26
|
import { getMessageDisplayTheme } from "./message-display.ts";
|
|
27
27
|
import { showMoreHintText } from "./show-more-hint.ts";
|
|
28
28
|
import {
|
|
@@ -60,6 +60,70 @@ const ASSISTANT_REENTRY_KEY = Symbol.for(ASSISTANT_REENTRY_DESCRIPTION);
|
|
|
60
60
|
const Box = (PiTui as any).Box;
|
|
61
61
|
const EDIT_WRITE_TOOLS = new Set(["edit", "write"]);
|
|
62
62
|
|
|
63
|
+
type CompactThinkingTheme = Pick<Theme, "fg" | "italic" | "bold">;
|
|
64
|
+
|
|
65
|
+
/** 与 compact-thinking 主渲染器共用的静态文字样式。 */
|
|
66
|
+
export function styleCompactThinkingText(
|
|
67
|
+
text: string,
|
|
68
|
+
theme: CompactThinkingTheme | undefined,
|
|
69
|
+
bold = false,
|
|
70
|
+
): string {
|
|
71
|
+
if (!theme) return text;
|
|
72
|
+
const colored = typeof theme.fg === "function" ? theme.fg("thinkingText", text) : text;
|
|
73
|
+
const weighted = bold && typeof theme.bold === "function" ? theme.bold(colored) : colored;
|
|
74
|
+
return typeof theme.italic === "function" ? theme.italic(weighted) : weighted;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** 与 compact-thinking 主渲染器共用的活动思考扫光动画。 */
|
|
78
|
+
export function animateCompactThinkingText(
|
|
79
|
+
text: string,
|
|
80
|
+
theme: CompactThinkingTheme | undefined,
|
|
81
|
+
animationFrame: number,
|
|
82
|
+
boldBase = false,
|
|
83
|
+
): string {
|
|
84
|
+
if (!theme) return text;
|
|
85
|
+
const characters = Array.from(text);
|
|
86
|
+
if (characters.length === 0) return "";
|
|
87
|
+
const highlightWidth = Math.max(1, Math.min(5, Math.ceil(characters.length * 0.28)));
|
|
88
|
+
const start = (animationFrame % (characters.length + highlightWidth)) - highlightWidth;
|
|
89
|
+
const end = start + highlightWidth;
|
|
90
|
+
const before = characters.slice(0, Math.max(0, start)).join("");
|
|
91
|
+
const highlighted = characters
|
|
92
|
+
.slice(Math.max(0, start), Math.min(characters.length, end))
|
|
93
|
+
.join("");
|
|
94
|
+
const after = characters.slice(Math.max(0, end)).join("");
|
|
95
|
+
const highlightedColored =
|
|
96
|
+
highlighted && typeof theme.fg === "function" ? theme.fg("text", highlighted) : highlighted;
|
|
97
|
+
const highlightedWeighted =
|
|
98
|
+
highlightedColored && typeof theme.bold === "function"
|
|
99
|
+
? theme.bold(highlightedColored)
|
|
100
|
+
: highlightedColored;
|
|
101
|
+
const highlightedText =
|
|
102
|
+
highlightedWeighted && typeof theme.italic === "function"
|
|
103
|
+
? theme.italic(highlightedWeighted)
|
|
104
|
+
: highlightedWeighted;
|
|
105
|
+
|
|
106
|
+
return (
|
|
107
|
+
styleCompactThinkingText(before, theme, boldBase) +
|
|
108
|
+
highlightedText +
|
|
109
|
+
styleCompactThinkingText(after, theme, boldBase)
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function formatThoughtDuration(durationMs: number) {
|
|
114
|
+
if (durationMs < 1_000) {
|
|
115
|
+
return `${Math.max(1, Math.round(durationMs))}ms`;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const totalSeconds = Math.max(1, Math.round(durationMs / 1_000));
|
|
119
|
+
const minutes = Math.floor(totalSeconds / 60);
|
|
120
|
+
const seconds = totalSeconds % 60;
|
|
121
|
+
if (minutes === 0) return `${seconds}s`;
|
|
122
|
+
return seconds === 0 ? `${minutes}m` : `${minutes}m ${seconds}s`;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export { formatThoughtDuration };
|
|
126
|
+
|
|
63
127
|
/**
|
|
64
128
|
* 逐条 assistant message 的摘要文本(无工具计数时可为空串):
|
|
65
129
|
* 思考时长在前,工具按消息内首次出现顺序排列;read 按非空路径去重。
|
|
@@ -864,15 +928,15 @@ function refreshTrackedComponents(): void {
|
|
|
864
928
|
for (const component of [...trackedAssistantComponents]) {
|
|
865
929
|
try {
|
|
866
930
|
if (config.mode !== "compact") detachAssistantExpansion(component);
|
|
867
|
-
|
|
868
|
-
else component.invalidate?.();
|
|
931
|
+
refreshTranscriptComponent(component);
|
|
869
932
|
} catch {
|
|
870
933
|
trackedAssistantComponents.delete(component);
|
|
871
934
|
}
|
|
872
935
|
}
|
|
873
936
|
for (const component of [...trackedToolComponents]) {
|
|
874
937
|
try {
|
|
875
|
-
|
|
938
|
+
// 共享实现负责 updateDisplay;invalidate 属于 compact-mode 的跟踪语义。
|
|
939
|
+
refreshTranscriptComponent(component);
|
|
876
940
|
component.invalidate?.();
|
|
877
941
|
} catch {
|
|
878
942
|
trackedToolComponents.delete(component);
|
|
@@ -771,7 +771,7 @@ function installToolExpandedBackground(): () => void {
|
|
|
771
771
|
const host = globalThis as any;
|
|
772
772
|
const previous = host[TOOL_EXPANDED_BACKGROUND_PATCH] as ToolExpandedBackgroundPatch | undefined;
|
|
773
773
|
if (previous) previous.dispose();
|
|
774
|
-
const prototype = ToolExecutionComponent.prototype;
|
|
774
|
+
const prototype = ToolExecutionComponent.prototype as unknown as { updateDisplay: () => void };
|
|
775
775
|
const original = prototype.updateDisplay;
|
|
776
776
|
const patch: ToolExpandedBackgroundPatch = {
|
|
777
777
|
active: true,
|
|
@@ -888,7 +888,7 @@ export default function (
|
|
|
888
888
|
compactThinking,
|
|
889
889
|
);
|
|
890
890
|
} else {
|
|
891
|
-
applyStyleMode(arg, ctx, hooks.toolGrouping);
|
|
891
|
+
applyStyleMode(arg as CompactStyleMode, ctx, hooks.toolGrouping);
|
|
892
892
|
}
|
|
893
893
|
return;
|
|
894
894
|
}
|